Framework: Do not ignore system-level env variables on config:cache

Created on 12 Mar 2018  路  12Comments  路  Source: laravel/framework

  • Laravel Version: 5.5
  • PHP Version: 7.2

Description:

The documentation describes:

Any variable in your .env file can be overridden by external environment variables such as server-level or system-level environment variables.

So the developer also thinks that the config:cache function will cache the system-level environment variable if set and not just values from the .env file. __But it does not (yet).__

Steps To Reproduce:

  1. Copy .env.example to .env. We use the env DB_HOST in our example.
  2. Set the environment variable DB_HOST on system-level.
  3. Run php artisan config:cache.
  4. See that the cached config is the value from the .env file and
    not the value from the __system__ environment variable.

All 12 comments

@pSchaub

Basically this shouldn't be the case, as Laravel itself loads it's environment variables using DotEnv, which is called with immutable set to true, so if a system environment variable already exists and is called DB_HOST, this should not get overridden.

Which webserver do you use, if I may ask?
Apache for example does NOT use environment variables from the operating system itself/set within the operating system itself per default, so you'd have to include those variables (source them) in eg. /etc/apache2/envvars and restart apache for them to be recognized by Laravel.
You can also have a look at mod_env which can do the same, with a little bit more configuration (keyword PassEnv Directive): https://httpd.apache.org/docs/2.4/mod/mod_env.html

Can you please try this?

If you dont want the system env to be overridden by your local .env file - then just remove that variable from your .env file?

@laurencei with 5.8 I'm having the exact oposite issue. System vars are only considered if I run artisan config:cache otherwise it keeps looking first for .env file even tough its available as system var... I cant find if this was intentional change or...

@rockoo - not sure mate. There were some issues with the whole env stuff that got fixed in 5.8.8 from memory. Try the latest version and see if the problem persists? If so, open a new ticket with all the details.

@rockoo long shot, but have you got to the bottom of this by any chance? Facing the same thing at the moment and it leaves me a bit baffled

@osteel sorry for the late reply. Unfortunatelly not for that version. The way I got around it was to execute a shell script on docker build that would run cache command... :/

@rockoo no worries, thanks for getting back to me. I'm facing this with Laravel 6.x. I am populating the .env file via a bash script instead for the time being, although this is not ideal!

@osteel If I come up with an idea of what is happening I will update you!

Quick update: I've now had to deploy the application to a production environment, where environment variables are injected into the container as server-level ones (no .env file). I had no other choice than to run config:cache as part of an initialisation script for the container, otherwise the environment variables are ignored.

We're using Laravel 6.2 at the moment.

@osteel I've also been looking into this in a container environment (although with L7) and it seems the documentation may be a little deceptive.
Reading the docs, I got the impression that config:cache would cache references to the environment variables (provided the calls to env() were in config files), so they could still be altered at runtime.

But it looks like when config:cache is run, it'll just grab the current value and cache that. So if your build system's environment variables don't happen to match prod, you're SOL.

This is a pain when trying to use Laravel inside a container, because you effectively have no way to cache at build time AND have dynamic config.

@laurencei Am I sort of on the right track here? Is there simply no way to get environment variables at runtime after a config:cache (even it the calls to env() are inside config files)?

@danielcotton You are right. You should run config:cache again in your container after you changed the environment variables. It's not enough to do it in your build. You need to run if after deployment.

See the docs:

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. Once the configuration has been cached, the .env file will not be loaded and all calls to the env function will return null.

Source: https://laravel.com/docs/8.x/deployment#optimizing-configuration-loading

You should run config:cache again in your container after you changed the environment variables.

Hey @pschaub , this is not always feasible. In kubernetes (or even in docker-compose) some ENV variables are set when the container starts up. When supporting multiple environments (dev, staging, production, etc.) and using continuous deployment, .env files are pretty much unworkable.

I would argue that system-level ENVs should take precedence over .env files.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

PhiloNL picture PhiloNL  路  3Comments

SachinAgarwal1337 picture SachinAgarwal1337  路  3Comments

fideloper picture fideloper  路  3Comments

shopblocks picture shopblocks  路  3Comments

JamborJan picture JamborJan  路  3Comments