Skip to content

Always load vars defined in .env files, providing .env.local.php for prod #501

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

Merged
1 commit merged into from
Jan 3, 2019
Merged

Always load vars defined in .env files, providing .env.local.php for prod #501

1 commit merged into from
Jan 3, 2019

Conversation

nicolas-grekas
Copy link
Member

@nicolas-grekas nicolas-grekas commented Dec 3, 2018

Q A
License MIT

This PR provides a nice experience where .env files are "always" loaded.
That means their purpose is easy to reason about: the committed files define the defaults (.env especially) - and .env.local defines local overrides.

A new .env.local.php is provided for prod, so that performance is not affected.
When .env.local.php is found, other .env files are ignored.

On the deployement side, this means it should be much easier to deal with .env files for people that can't easilly deal with real env vars:

  • if you use real env vars they always win
  • logically, .env files are always loaded (to define defaults)
  • on prod, one can dump a .env.local.php file for max performance

The plan is to add a new flex command to create this file and ease deployments:
composer dump-env prod

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.

@nicolas-grekas
Copy link
Member Author

nicolas-grekas commented Dec 10, 2018

@symfony/deciders votes welcome.

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.

@nicolas-grekas nicolas-grekas changed the title Always load vars defined in .env files, using .env.local.php for prod cache Always load vars defined in .env files, using .env.cache.php for prod on the web Dec 11, 2018
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.

@nicolas-grekas
Copy link
Member Author

(updated to use .env.cache.php instead of .env.local.php)

@lyrixx
Copy link
Member

lyrixx commented Dec 11, 2018

Things are getting really complicated IMHO. We have so many .env files.
It was much simpler when we were using .yaml file.
I totally understand why we needed to switch to .env file, but IMHO we should rethink everything.

For example why do we need a committed .env file while we say that we need to defined a default value for each env var in the services.yaml ? (or another file). We need a default value for the default value ?
(Actually, this is a rhetorical question. I know the reason: because if we want to use env var (not resolved I mean) even in the DIC we need this .env).

But how many people really need really dynamic values ? very few.
We are making things really complicated because of a few people, leaving so many others behind
There are plenty of questions like "how does env var work", "what should I put in my env var", "how do I change my DB in test" etc etc. Theses question are on the table almost everyday on slack (different slack / different channel).
Most of the people I work with / meet / train or discuss with do not understand where we are going and think it's now more complicated than before.

Symfony 4 + Flex + MakerBundle is really cool and easy. But theses env var really needed to be re-thought

@nicolas-grekas
Copy link
Member Author

@lyrixx 💯 - that's what this PR provides :)

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.

@lyrixx
Copy link
Member

lyrixx commented Dec 11, 2018

BTW, this PR is a very good move 👍

About this point (the part "which you should"):

if you use real env vars they always win (which you should - see https://12factor.net/)

I totally disagree. It's like always : it depend. Many applications are hosted on bare metal, and will not move. Using env var make things more complicated because you need to load them for FPM + CLI + CRON + Worker. Using a simple .env file (like you porpose) is much more simple.

So we should not say :

you should use env var.

Declaring parameter in .env for just fine and easy for many!

@Simperfit
Copy link
Contributor

👍

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.

@ghost ghost merged commit 3e471cb into symfony:master Jan 3, 2019
ghost pushed a commit that referenced this pull request Jan 3, 2019
@nicolas-grekas nicolas-grekas deleted the env-always-load branch January 3, 2019 13:09
@mhujer
Copy link
Contributor

mhujer commented Jan 4, 2019

@nicolas-grekas This PR probably causes PHPUnit to fail:

Notice: Undefined index: APP_ENV in C:\dev\htdocs\sf-rec\config\bootstrap.php on line 19

Steps to reproduce:

composer create-project symfony/skeleton sf-rec
cd sf-rec
composer require --dev phpunit/phpunit
vendor\bin\phpunit # or vendor/bin/phpunit on Linux


Notice: Undefined index: APP_ENV in C:\dev\htdocs\sf-rec\config\bootstrap.php on line 19
PHPUnit 7.5.1 by Sebastian Bergmann and contributors.


Time: 93 ms, Memory: 2.00MB

No tests executed!

@mhujer
Copy link
Contributor

mhujer commented Jan 4, 2019

Nevermind, just found #512

weaverryan added a commit to symfony/symfony-docs that referenced this pull request Jan 5, 2019
…loaded (weaverryan)

This PR was merged into the 4.1 branch.

Discussion
----------

Documenting changes recipe 501 - where .env is always loaded

See symfony/recipes#501

This basically documents *part* of what is included in #10793. That PR also documents the Flex `composer sync-recipes --force` and `composer dump-env prod`  commands, neither of which exist yet. When those are merged / tagged, I'll finish that PR.

Note: after merging to 4.2, the URLs at the bottom of `dot-env-changes` need to be changed to point to the 4.2 recipes.

Thanks!

Commits
-------

203d93a Documenting changes recipe 501 - where .env is always loaded
@eschultz-magix
Copy link

eschultz-magix commented Jan 8, 2019

For example why do we need a committed .env file while we say that we need to defined a default value for each env var in the services.yaml ? (or another file). We need a default value for the default value ?
(Actually, this is a rhetorical question. I know the reason: because if we want to use env var (not resolved I mean) even in the DIC we need this .env).

That's a good point and I also see a duplication in here. From the documentation (https://symfony.com/doc/current/configuration/external_parameters.html):

You can also give the env() parameters a default value: the default value will be used whenever the corresponding environment variable is not found:

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

By default, the kernel loads the services.yaml and a services_<env>.yaml for each environment as an extension to the services.yaml. Both files allow to set default values like the .env file. So why is the .env file REALLY necessary? Or on the other hand: Wouldn't it be better to deprecate the env(ENV_NAME) parameter feature then?

@Pierstoval
Copy link
Contributor

Default value and Necessary env var are not the same thing. Default value means "If we don't have it, use this". Necessary env var means "We need this env var, and possibly with a valid value".

A .env file is here to specify the necessary values. What it contains "by default" is just values "that should work", but sometimes it does not work.

For instance, check the Recaptcha recipe: Google credentials are mandatory, but they won't break the app if they're not valid. They will break only the portions that actually use a captcha.

nicolas-grekas added a commit to symfony/flex that referenced this pull request Jan 21, 2019
…al.php (nicolas-grekas, renanbr)

This PR was merged into the 1.2-dev branch.

Discussion
----------

Add "dump-env" command to compile .env files to .env.local.php

This adds a new command that compiles .env files to .env.local.php:
```
$ composer dump-env prod
Successfully dumped .env files in .env.local.php
```

The generated file is used in symfony/recipes#501

Commits
-------

7e561d5 add --empty option
31b12b1 Add "dump-env" command to compile .env files to .env.local.php
bocharsky-bw added a commit to bocharsky-bw/symfony-docs that referenced this pull request Jun 8, 2019
Looks like according to these changes: symfony/recipes#501 - Dotenv component is suggested to be added to `require` section of `composer.json`. Both `symfony/skeleton` and `symfony/website-skeleton` require it on prod
javiereguiluz added a commit to symfony/symfony-docs that referenced this pull request Jun 10, 2019
This PR was merged into the 3.4 branch.

Discussion
----------

Require Dotenv component without --dev

Looks like according to these changes: symfony/recipes#501 - Dotenv component is suggested to be added to `require` section of `composer.json`. Both `symfony/skeleton` and `symfony/website-skeleton` require it on prod

Commits
-------

3f7594d Require Dotenv component without --dev
wouterj added a commit to symfony/symfony-docs that referenced this pull request Oct 21, 2020
…s logic (cristi-contiu)

This PR was submitted for the 4.1 branch but it was merged into the 4.4 branch instead.

Discussion
----------

[Deployment] Update deployment docs with new .env files logic

The [changes from last year regarding how the ``.env`` files are loaded](https://symfony.com/doc/current/configuration/dot-env-changes.html) can affect production deployments. Vendors like [Heroku](https://devcenter.heroku.com/articles/deploying-symfony4#environment-variables) give recommendations based on documentation that no longer applies: "It is recommended that you do not use the symfony/dotenv package in production".

The ``symfony/dotenv`` has been moved from ``require-dev`` to ``require``, so the note I removed in this PR no longer applies: symfony/skeleton#122 , symfony/website-skeleton#132 and symfony/demo@7ead1e4 . Loading ``.env`` files in production will work without any changes in composer.json.

Putting ``symfony/dotenv`` in ``require-dev`` (or not moving it to ``require`` during an upgrade from older versions of Symfony & recipes) can potentially break your app: if the DotEnv class is missing, the [`config/bootstrap.php` file inside the FrameworkBundle's recipe will throw a RuntimeException](https://github.com/symfony/recipes/blob/master/symfony/framework-bundle/3.3/config/bootstrap.php#L14) . Also see symfony/recipes#501

The note now contains the right way to handle these files in production, by using ``$ composer dump-env prod`` in case you do not want the ``.env`` files to be processed on every request, also suggesting the ``--empty`` flag if you want to rely exclusively on "real" environment variables .

Commits
-------

b905b57 Update deployment docs with new .env loading
This pull request was closed.
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.

10 participants