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)

Most upvoted comments

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:clear complains due to a missing SENTRY_DSN. Setting SENTRY_DSN= in a .env works, but it is not something I’d commit.

It’s not discouraged anymore, it’s actually always loaded now. See composer dump-env prod from flex.

@nicolas-grekas .env is not supposed to exist during docker build operations, since the image is to be used for publishing (keyword public), and then adapted with different .env. Providing a .env to be added to the image (with fake/invalid values) is also a problem, as @dunglas said:

(excluding such files is best practice)

In a production system following 12FA principles (Dokku, Heroku, K8s, Swarm), .env files 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 that bin/console is used in composer hooks 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:

FROM ...

ADD ...

RUN SENTRY_DSN= composer install -a

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/console that requires to boot up the container, and it’s itself used to run cache: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 starting bin/console cache:warmup, you’re stuck with errors.

Let me be more clear then: in applications (in general, not symfony), .env is not committed, and .env.dist is 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 do bin/console cache:clear in the Dockerfile. Not warming up the cache during docker build is bad, as it means a slow container start.