symfony: [RFC][DX] Defaulting missing env variables to empty string
Description
I’m hitting a constant issue while deploying my Symfony apps with Docker: during the Docker build I want to issue the cache:warmup command, and in that environment a lot of env variables are missing, because I’m not actually in the prod environment.
This forces me to define in the parameters a bunch of default values for env variables, so the container dump process will not complain about those. And those values are normally defaults or empty string.
I would like to suggest a new behavior: not complaining about missing env vars, at least during cache warmup: this would allow us to avoid defining all those variables as empty, and concentrate on having them just in the real prod environment.
Example
This could be done in some way like bin/console cache:warmup --ignore-missing-envs. WDYT?
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 4
- Comments: 35 (29 by maintainers)
To me the best practice would be to list them in the .env file, instead of using parameters. That allows documenting them and ease discovery of what your app needs. Using the flag might as well hide mistakes. Another best practice is that warmup should not reference any env var, so I’m not totally sure this builds on a legit root issue.
@Jean85 this is indeed still an issue: hitting it as
cache:clearcomplains due to a missingSENTRY_DSN. SettingSENTRY_DSN=in a.envworks, but it is not something I’d commit.@nicolas-grekas
.envis not supposed to exist duringdocker buildoperations, since the image is to be used for publishing (keyword public), and then adapted with different.env. Providing a.envto be added to the image (with fake/invalid values) is also a problem, as @dunglas said:In a production system following 12FA principles (Dokku, Heroku, K8s, Swarm),
.envfiles won’t exist at all, as secrets as mounted as individual environment variables that will only ever exist at runtime, and never at build time.@Jean85 I think the problem is more to the core: the application should not be bootstrapped to run things like
cache:clear, as it can only be bootstrapped when all environment and configurations are set. The fact thatbin/consoleis used incomposerhooks is the root of the issue, so we’re hitting a bit of a chicken-egg problem.Yes, I just clarified that this (the empty value) should not be put in
.env, as it is also misleading and also confuses security scanners.For now, I’m working around the issue in key components of the application that need to run without environment by force-feeding variables where needed, such as in my
Dockerfile:Yes @nicolas-grekas, but .env using is discouraged in prod environments, and I’m having this issue while building for that env.
Also, as rightly pointed out by @linaori on Slack, it seems that the errors stems from the fact that we have a “chicken and egg” kind of issue, with
bin/consolethat requires to boot up the container, and it’s itself used to runcache:warmup, so you can’t run it with a warmed up cache. So, if you use any env variable in something that is boostrapped while startingbin/console cache:warmup, you’re stuck with errors.Let me be more clear then: in applications (in general, not symfony),
.envis not committed, and.env.distis committed instead.What symfony does is then certainly questionable (and I am questioning it).
@nicolas-grekas See for example here: https://github.com/symfony/recipes/blob/3b19bd94886555df1997b441b6cf6a1fab088f3a/doctrine/doctrine-bundle/1.6/config/packages/doctrine.yaml#L2-L6
Workarounds like this are necessary for a successful
docker build, if we dobin/console cache:clearin theDockerfile. Not warming up the cache duringdocker buildis bad, as it means a slow container start.