Managing environment variables for different environments, such as production and development, is crucial for deploying applications effectively. In this post, I’ll demonstrate how to use Docker Compose with .env files to easily switch between these environments, using the example of setting a DEBUG_LEVEL variable to control application logging.
To start, you’ll need different .env files for each environment:
1. .env (Common configuration)
ENVIRONMENT=prod UBUNTU_VERSION=24.04
This common .env file sets the default ENVIRONMENT to prod (production) and specifies the Ubuntu version. These variables are used across all environments.
2. .env.prod (Production-specific configuration)
DEBUG_LEVEL=ERROR
In the production environment, DEBUG_LEVEL is set to ERROR to minimize logging output and avoid exposing sensitive information.
3. .env.dev (Development-specific configuration)
DEBUG_LEVEL=DEBUG
In the development environment, DEBUG_LEVEL is set to DEBUG to provide detailed logs for troubleshooting and development purposes.
The compose.yaml file is set up to dynamically load the appropriate environment file based on the ENVIRONMENT variable, which can be set either in the shell or in the .env file:
services: test: image: ubuntu:${UBUNTU_VERSION} command: ["sh", "-c", "env"] env_file: - .env.${ENVIRONMENT}
This configuration uses the env_file directive to load the environment-specific file (.env.prod or .env.dev) based on the value of the ENVIRONMENT variable.
If the ENVIRONMENT variable is set in both the .env file and the shell, the value set in the shell will take precedence. This is useful for temporarily overriding the environment setting without modifying the .env file. For example:
Setting the ENVIRONMENT variable in the shell:
export ENVIRONMENT=dev
If you also have ENVIRONMENT=prod set in the .env file, the shell setting will overwrite it, and the development environment settings will be used:
$ docker compose up [+] Running 2/1 ✔ Network tmp_default Created 0.1s ✔ Container tmp-test-1 Created 0.1s Attaching to test-1 test-1 | DEBUG_LEVEL=DEBUG test-1 | HOSTNAME=f9002b77bc79 test-1 | HOME=/root test-1 | PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin test-1 exited with code 0
If you want to use the production settings instead, you can unset the shell variable and rely on the value in the .env file:
unset ENVIRONMENT
Then, when you run docker compose up again, the output will reflect the production environment:
$ docker compose up [+] Running 2/1 ✔ Network tmp_default Created 0.1s ✔ Container tmp-test-1 Created 0.1s Attaching to test-1 test-1 | DEBUG_LEVEL=ERROR test-1 | HOSTNAME=f9002b77bc79 test-1 | HOME=/root test-1 | PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin test-1 exited with code 0
By using .env files and setting the ENVIRONMENT variable in the shell, you have the flexibility to manage environment variables dynamically. This approach simplifies switching between environments and ensures consistent deployment settings, minimizing the risk of configuration errors and improving application reliability.