How to Manage Environment Variables for Production and Development with Docker Compose
Reading time: 34 – 57 minutesManaging 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.