While planning and implementing a deployment workflow using docker-compose for Orchestration, I had invested a lot of time regarding several and reoccurring problems in combination with the Dotenv component of Symfony. So I would like to share my findings and my way of solving this, so you can bring your application quicker into production.
The problem
For deployments in test and production, I use a separate deployment repository containing the configuration like an .env
file for the variables for that actual specific environment (e.g. prod) which is automatically written in the $_SERVER
environment of the container by docker. But when running the container in these environments, I noticed that the dev configuration is suddenly used.
So I went to debugging this issue until I noticed that after builds, suddenly a wild .env
file appeared out of nowhere in the root directory of the project. Which was kinda weird because it was never committed, only the .env.dist
existed in the repository.
The explanation
By default, Symfony and docker-compose use a .env
file which is found in the root of the directory. So this .env file would be read by both, which is mostly no problem during development.
When running composer install
the post-scripts of Symfony flex actually copy the .env.dist
to .env
if it does not exist. If this had landed in production, in my case the configuration would be as if it were in development. This explains why this wild file suddenly appears out of nowhere. Of course, while developing a .env
already existed, so this issue didn’t occur.
Since Symfony always prefers environment variables from the local .env
file in the root of the project, these overwrite the ones from the $_SERVER
which should actually be the ones to use.
So, I thought about how can this be solved for good and came up with the following solutions.
The solution
To be 100% sure there will not be a problem in the future with this, we have committed ourselves to move the .env
file (which is empty) for symfony into a separate directory config/environment/.env
. Like this, Symfony won’t load the .env
file in the root of the project, and they do not interfere with the variables for docker.
Symfony projects prior to 5.1
The path of the .env
file can be changed in config/bootstrap.php
. I just create an empty .env
file in this directory to omit runtime errors.
(new Dotenv(false))->loadEnv(dirname(__DIR__) . '/config/environment/.env');
Symfony projects 5.1+
After updating several applications to the 5.1 I have encountered that the bootstrap.php
is actually removed. But it still could be used in future versions, so I used it until 5.3.
The reason is that Symfony introduces the new runtime, which is available from version 5.3 and upwards. This added many new features and integrations, also regarding the Dotenv component.
After reading the documentation, I have gladly found methods for configuration of this path within either the $_SERVER
environment or composer.json. I am going to use the composer version, since it is nicer IMHO.
"extra": {
"symfony": {
"allow-contrib": false,
"require": "5.4.*"
},
"runtime": {
"dotenv_path": "config/environment/.env"
}
},