Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Allow to override .env files for specific environments #466

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 9 commits into from

Conversation

dunglas
Copy link
Member

@dunglas dunglas commented Sep 21, 2018

Q A
License MIT

As discussed in #465 and symfony/symfony#28533, this PR makes Symfony behaving like Create React App, Rails or Sinatra: the following files, starting from the bottom. The first value set (or those already defined in the environment) take precedence:

  • .env - The Original®
  • .env.dev, .env.test, .env.prod... - Environment-specific settings.
  • .env.local - Local overrides. This file is loaded for all environments except test.
  • .env.dev.local, .env.test.local, .env.prod.local... - Local overrides of environment-specific settings.

The default envs are env and test.

It also fixes #366 (comment): when running bin/console -e=prod, the .env.prod file will be loaded (if APP_ENV is not already defined).

Needs:

Closes #465, #366, #408.

Copy link

@ghost ghost left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request does not pass validation.

Copy link

@ghost ghost left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request does not pass validation.

Copy link

@ghost ghost left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request passes validation.

Copy link
Contributor

@ogizanagi ogizanagi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

symfony/flex#318 would be required after this one for Flex to stop updating the phpunit.xml.dist file in favor of the .env.test file.

@dunglas
Copy link
Member Author

dunglas commented Sep 21, 2018

@maxhelias @ogizanagi I was thinking about introducing an env var simply called LOAD_ENV. When defined it will always load the given env file. It would resolve both of your comments, and can replace the -e argument in console.

To run the command in prod env: LOAD_ENV=prod bin/console
To run the integrated web server in prod env: LOAD_ENV=prod php -S 127.0.0.1:8000 -t public

WDYT?

Copy link
Contributor

@sroze sroze left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really like the idea.

Copy link

@ghost ghost left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request passes validation.

Copy link

@ghost ghost left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request passes validation.

Copy link

@ghost ghost left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request passes validation.

Copy link

@ghost ghost left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request passes validation.

@dunglas
Copy link
Member Author

dunglas commented Sep 21, 2018

To upgrade, users will have to use a script like this one:

cat composer.json | jq --indent 4 '.require["symfony/flex"] = "^2.0"' > composer.tmp
mv composer.tmp composer.json
cp .env .env.local
cp .env.dist .env
sed -i'' -e 's/\/.env/\/.env.local\
\/.env.*.local/' .gitignore

Copy link

@ghost ghost left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request passes validation.

Copy link

@ghost ghost left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request passes validation.

@B-Galati
Copy link
Contributor

B-Galati commented Oct 30, 2018

Should we also deprecate the default value notation of services files?
i.e.:

# config/services.yaml
parameters:
    env(DATABASE_HOST): localhost

https://symfony.com/doc/current/configuration/external_parameters.html#environment-variables

Copy link

@ghost ghost left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request passes validation.

Copy link

@ghost ghost left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request passes validation.

Copy link

@ghost ghost left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request passes validation.

Copy link

@ghost ghost left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request passes validation.

Copy link

@ghost ghost left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request passes validation.


Debug::enable();
}
$kernel = require __DIR__.'/../src/bootstrap.php';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not a big fan of having a bootstrap.php file. what about moving the logic to the Kernel class instead?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately it won't work for PHPUnit (it is not able to call a method to bootstrap).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The src/bootstrap.php file doesn't bother me. But if you prefer, we could move this logic to the kernel and only keep a test/bootstrap.php file used by phpunit? That's already common to need such a file to add specific code before running tests and would avoid requiring 2 bootstrap.php files

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having a static method on Kernel and then reusing it in a bootstrap file for PHPUnit sounds like a better idea to me.

@ogizanagi
Copy link
Contributor

@B-Galati : What do you mean in #466 (comment)?
I fail to understand how it relates with this PR? 🤔

@B-Galati
Copy link
Contributor

@ogizanagi it does not relate sorry. I will open an issue on Symfony repository.


$envFromEnv = $_SERVER['APP_ENV'] ?? $_ENV['APP_ENV'] ?? null;
$env = $envFromEnv ?? 'dev';
$prod = 'prod' === $env;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest to go one step further and to not load .env if the environment name doesn't start with dev or test (.env.test-e2e will be loaded, but not .staging). WDYT?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My opinion is that it complicates everything to introduce more and more exceptions and would make it far from intuitive. The prod env restriction has a reason, it's a safeguard for real production environments.
For other env, I don't understand the reasons yet. The main reason for this feature to exist is env.test and that's how it'll be used 95% of the time. But some applications defines their own specific symfony env(s) and may also benefit from this. And if you don't, then you shouldn't care putting arbitrary restrictions on a feature already based on conventions :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’m fine with this


$kernel = require __DIR__.'/../src/bootstrap.php';
$application = new Application($kernel);
$application->run($input);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this variable $input is not defined though the code cannot work


use Symfony\Bundle\FrameworkBundle\Console\Application;

if (!class_exists(Application::class)) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the autoload has not yet been called at this point so this condition is always false and always throw the exception even if framework-bundle is installed

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe because there is no require __DIR__.'/../vendor/autoload.php'; in this file

@@ -0,0 +1,29 @@
<?php

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this class lives under src/ which is autoloaded, so composer excepts a class which this file is not. It gives the following error :

In FileLoader.php line 168:
                                                                                                                                                        
  The autoloader expected class "App\bootstrap" to be defined in file "/srv/app/vendor/composer/../../src/bootstrap.php". The file was found but the c  
  lass was not in it, the class name or namespace probably has a typo in /srv/app/config/services.yaml (which is loaded in resource "/srv/app/config/s  
  ervices.yaml").                                                                                                                                       
                                                                                                                                                        

In DebugClassLoader.php line 204:
                                                                                                                                                        
  The autoloader expected class "App\bootstrap" to be defined in file "/srv/app/vendor/composer/../../src/bootstrap.php". The file was found but the c  
  lass was not in it, the class name or namespace probably has a typo.   

@dunglas
Copy link
Member Author

dunglas commented Nov 8, 2018

Closing in favor of #481

@dunglas dunglas closed this Nov 8, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.