I am currently deploying a Laravel project on my shared hosting account. It is an open project and hosted on GitHub as a public repository. As a result I'm using dynamic variables set by an .htaccess file in my database.php configuration file for my production environment. This allows me to also update my deployment using a git pull command on my host which helps speed up work.
The database.php file has something similar to
$database = $_SERVER['DBNAME'];
$database_user = $_SERVER['DBUSER'];
This is much like what is done when deploying to PagodaBox & works perfectly fine for the application with all things functioning as expected in the browser, no complaints.
The problem I have is that artisan is unable to use these variables and will attempt instead to connect to the database using what I believe to empty variables when processing a migrate instruction. I get an error that artisan tried to connect to the databases with no password. I have been calling artisan using --env=production and have tested this but found that it will only work if the database.php file has the variables specified explicitly instead of as environment variables.
Is there a way of causing artisan to "see" these environment variables?
answers that have proved useful to me so far:
http://forums.laravel.io/viewtopic.php?pid=8455
and
Environment driven database settings in Laravel?
Because Artisan is a CLI PHP request - the request never hits the .htaccess file - and therefore your variables are never set.
As a workaround - you could define the variables inside the artisan file itself on line 3 (just after the <?php)
$_SERVER['DBNAME'] = 'test';
$_SERVER['DBUSER'] = 'something';
edit: I just noticed you said this is public hosted on github - so you wont want to include your username/password in the file? Maybe put the artisan file as part of the .gitignore group - so you dont push/pull that single file?
The capability to set up environment variables is built in to Laravel, so there's no reason to do it in .htaccess. Laravel's built-in way works with artisan without any trouble.
See this part of the docs about environment variables you would like to protect.
http://laravel.com/docs/configuration#protecting-sensitive-configuration
Quoting:
... create a .env.local.php file within the root of your project [...] The .env.local.php should return an array of key-value pairs, much like a typical Laravel configuration file:
<?php
return array(
'TEST_STRIPE_KEY' => 'super-secret-sauce',
);
All of the key-value pairs returned by this file will automatically be available via the $_ENV and $_SERVER PHP "superglobals". You may now reference these globals from within your configuration files:
'key' => $_ENV['TEST_STRIPE_KEY']
Be sure to add the .env.local.php file to your .gitignore file. This will allow other developers on your team to create their own local environment configuration, as well as hide your sensitive configuration items from source control.
Add your private environment variables
<?php
return array(
'MY_SECRET_KEY' => 'super-secret-sauce',
);
Related
I would like to ask how can I possibly dynamically load different env file setting?
I have read the documentation, I have created two files (.env and .env.uat)
.env for development and .env.uat for client testing environment, and it depends on the url to use different env file, eg: (company-dev) -> .env, (company-uat) -> .env.uat
I have added these two lines of code to bootstrap/app.php, actually it works, but when I want to execute php artisan migrate, then it said that HTTP_HOST couldn't found, so it will load the .env.uat as the fallback file. Can someone tell me where should I modify code please? Thanks!! (Actually I knew I can manually change the .env file in different environment everytime, I am seeking some automatic way to recognise the env file for me.
$envFile = $_SERVER['HTTP_HOST'] == 'xxx-dev-testing.com' ? '.env' : '.env-uat';
$app->loadEnvironmentFrom($envFile);
There's no HTTP_HOST in the command line. You'll need a different approach. Ultimately, though, .env shouldn't be in version control at all. Your UAT environment would just have a .env with different values.
I use laravel framework on 2 websites,
The application backend is one, but view paths is different for each site.
There is nginx variable "WEBSITE", which is available in PHP (phpinfo prints it).
When I run application locally, all is right. But in production, I get exception what variable is not exists.
I discovered what during deploy running command php artisan config:cache, which cached all config in "bootstrap" directory. I don't may delete this command, because it ups performance of site. This command caches all config including app/config/view.php file that descript changes in view paths, like this
'paths' => [
resource_path('views/' . env('WEBSITE')),
],
but config already cached without variable and in this form is delivered to the production.
I don't understand how fix this problem, other that edit all views, base layouts for both sites. Does anyone know how to solve this problem in a simple way?
Just add a fallback by explicitly adding WEBSITE=somewebsiteurl in your production sites .env, then re-cache the config and try if it works.
I stumbled across this https://laravel.com/docs/5.4/configuration#configuration-caching in the documentation and it confused me a bit.
When I want an environment variable I use the env() function to return what I want. According to the above link it says I should be using the config() function instead to ensure that on production I am accessing the values through a cache.
e.g. These both return the same thing
env('APP_URL')
vs
config('app.url')
So should I be using config() or env() inside my app?
I assume that if I add a new env variable I will also need to update my config files?
You should never use env() in the code directly. It's a good practice to use config(). In config files use env() to get the data from .env file.
In this case, you can easily override config values at runtime or during testing.
You also can use config caching.
To give your application a speed boost, you should cache all of your configuration files into a single file using the config:cache Artisan command.
Another reason is described in the docs:
You should typically run the php artisan config:cache command as part of your production deployment routine. If you execute the config:cache command during your deployment process, you should be sure that you are only calling the env function from within your configuration files.
I installed fresh Laravel 5 copy.
My detectEnvironment function is defined this way:
$app->detectEnvironment(function()
{
return 'local';
return getenv('APP_ENV') ?: 'production';
});
In config\local I've created database.php file:
<?php
return [
'nothing' => 'new',
];
I run php artisan clear-compiled.
My index method of WelcomeController is defined this way:
public function index(Application $app)
{
echo $app->environment();
var_dump($app['config']['database']);
//echo $app['config']['database'];
return view('welcome');
}
Application was imported this way: use Illuminate\Foundation\Application;
The result I get is:
local array(1) { ["nothing"]=> string(3) "new" }
whereas I would expect Laravel to cascade config file with production one (with the default config\database.php file.
The strange thing is that even if I comment the line return 'local'; run again php artisan clear-compiled it shows:
production array(1) { ["nothing"]=> string(3) "new" }
so it seems it always loads database.php file content (this one from local folder) and overrides main database.php file. It works fine again when I change this file name to for example aaa.php.
Is it a bug or maybe environment configuration shouldn't be stored inside config directory? But if not, where should they be store? I don't know if it's a bug or a feature so if anyone knows more about it, please give me a clue.
Although in documentation for Laravel dev (5.0) there is info that configuration will cascade it's not true. I have tested it about 2 weeks ago and it seems at the moment the only way to have different values for environments is using ENV file where you put custom values for current environment. Putting settings in directories won't work as it used to work however it's possible it will change or maybe has been already changed for last 2 weeks.
There's a package that brings the cascading config system back to Laravel 5.
Disclaimer: I am the author.
For me it looks like defect in Laravel 5 dev branch. I was able to work around by adding manual environment detection and configuration. This code does it.
'default' => $app->environment()=='testing'?'sqlite':'mysql',
It is easy to configure Laravel 5 environment.
Open your root application folder and find ".env.example",
Copy and rename into ".env",
Please fit ".env" file into your environment,
If you use GIT, make sure you don't push this file to your GIT repository.
For 'complete explanation', I write this configuration here.
Edited;
I quote from the developer in His github repository readme.md file;
phpdotenv is made for development environments, and generally should
not be used in production. In production, the actual environment
variables should be set so that there is no overhead of loading the
.env file on each request. This can be achieved via an automated
deployment process with tools like Vagrant, chef, or Puppet, or can be
set manually with cloud hosts like Pagodabox and Heroku.
So, you need to create ".env" file per machine and don't use ".env" file in your production server.
I am very confused about the environment in Laravel 4.2. I have setup my environment folders in the /config folder. I then added the following:
$env = $app->detectEnvironment(array(
'production' => array('my-server-name'),
'local' => array('my-local-name')
));
where my-server-name and my-local-name where taken from the terminal by running hostname.
When I do this however, no matter where I run the code, the environment is always production. What am I doing wrong?
I think you're not using detectEnvironment correctly. In this function, YOU are supposed to return the environment used, based on a config file, or an external environment variable - not get the environment. If you look at the documentation, you'll see some samples on how to use detectEnvironment properly, with both config file, or external variable (e.g. set the environment variable MY_LARVEL_ENV=local at the command line, and access it using $_SERVER['MY_LARAVEL_ENV'] inside the function, to return the proper environment.
in the beginning of a project in laravel could be a really mess with the roots and all that stuff, so I recommend you to follow this tutorial!
https://github.com/JeffreyWay/Laravel-4-Generators
Go to the root of your project on cmd and follow the steps,once your ready, just type:
php artisan generate:scaffold theNameOfYourTable
And say yes!
It will create you all te MVC, Seeders,Standar of your project, and some other awesome staff. ;)