.env variables vs global.php for environment-specific configuration
0 reputation · 24 Nov 2020, 23:50 UTC
0 reputation · 24 Nov 2020, 23:50 UTC
Contao CMS allows developers to manage environment-specific settings using either a .env file via the Symfony DotEnv component or the global.php configuration file. While .env is standard for keeping sensitive credentials out of version control, global.php provides a structured PHP-based override mechanism.
A critical trade-off exists when moving from a local development environment to a production server. Local setups often rely on permissive file access for .env files, but production environments may impose stricter permissions or utilize system-level environment variables that can conflict with file-based configurations.
Additionally, the interaction between these two methods and the Symfony cache can lead to inconsistencies where production settings do not update immediately after a file change.
.env and global.php affect the reliability of the bin/console cache:clear command in production?Neither file is resilient against restrictive permissions on its own. The most permission-tolerant production pattern is a real process environment variable — set in the PHP-FPM pool configuration, a systemd unit, or injected from a secret store — because nothing inside the application tree has to be readable at runtime. If you must choose between the two files, global.php is usually the safer option: it ships with the application, is read by the same PHP process that loads the rest of the configuration, and does not depend on a separate dotfile surviving deployment with the correct ownership.
On the second question: cache:clear does not reconcile the two sources. In prod, container parameters are compiled into the cache, so editing .env has no effect while a later layer — typically global.php or a real environment variable — still supplies the same key.
Well-established in Symfony-based Contao:
.env early, before the container is built, so those values become container parameters.global.php is applied during configuration loading and ends up compiled into the container.prod parameters are not re-read on every request; a rebuild is required.Likely, but version-sensitive: the exact precedence between the two layers. Do not assume .env always wins. Treat this as requiring verification against your installed Contao and Symfony versions.
| Layer | Read by | Survives restrictive permissions? | Refresh needed |
|---|---|---|---|
| Process env (PHP-FPM, systemd) | PHP process | Yes — no file required | FPM restart |
.env | DotEnv, as PHP user | Only if readable by the PHP user | Cache rebuild |
global.php | App config loader | Yes, if the app tree is readable | Cache rebuild |
global.php defines the same key as .env, keep exactly one source.sudo -u www-data APP_ENV=prod php bin/console cache:clear
sudo -u www-data APP_ENV=prod php bin/console cache:warmup
.env and global.php; the public webroot can serve neither.Which Contao/Symfony version are you running, and does global.php actually define the key in question? If it does not, the stale value is coming from a real process environment variable or from an un-rebuilt cache, and comparing the two files is the wrong place to look.
Do not commit production credentials to global.php. Keep secrets in environment variables or a secret store, keep .env out of version control, and avoid running cache commands as root, which can leave root-owned cache files the PHP user cannot rewrite.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.