Environment variables precedence in Docker Compose
When the same environment variable is set in multiple sources, Docker Compose follows a precedence rule to determine the value for that variable in your container's environment.
This page explains how Docker Compose determines the final value of an environment variable when it's defined in multiple locations.
The order of precedence (highest to lowest) is as follows:
- Set using
docker compose run -ein the CLI. - Set with either the
environmentorenv_fileattribute but with the value interpolated from your shell or an environment file. (either your default.envfile, or with the--env-fileargument in the CLI). - Set using just the
environmentattribute in the Compose file. - Use of the
env_fileattribute in the Compose file. - Set in a container image in the
ENV directive.
Having any
ARGorENVsetting in aDockerfileevaluates only if there is no Docker Compose entry forenvironment,env_fileorrun --env.
Simple example
In the following example, a different value for the same environment variable in an .env file and with the environment attribute in the Compose file:
$ cat ./webapp.env
NODE_ENV=test
$ cat compose.yaml
services:
webapp:
image: 'webapp'
env_file:
- ./webapp.env
environment:
- NODE_ENV=production
The environment variable defined with the environment attribute takes precedence.
$ docker compose run webapp env | grep NODE_ENV
NODE_ENV=production
Advanced example
The following table uses VALUE, an environment variable defining the version for an image, as an example.
How the table works
Each column represents a context from where you can set a value, or substitute in a value for VALUE.
The columns Host OS environment and .env file is listed only for illustration purposes. In reality, they don't result in a variable in the container by itself, but in conjunction with either the environment or env_file attribute.
Each row represents a combination of contexts where VALUE is set, substituted, or both. The Result column indicates the final value for VALUE in each scenario.
| # | docker compose run | environment attribute | env_file attribute | Image ENV | Host OS environment | .env file | Result |
|---|---|---|---|---|---|---|---|
| 1 | - | - | - | - | VALUE=1.4 | VALUE=1.3 | - |
| 2 | - | - | VALUE=1.6 | VALUE=1.5 | VALUE=1.4 | - | VALUE=1.6 |
| 3 | - | VALUE=1.7 | - | VALUE=1.5 | VALUE=1.4 | - | VALUE=1.7 |
| 4 | - | - | - | VALUE=1.5 | VALUE=1.4 | VALUE=1.3 | VALUE=1.5 |
| 5 | --env VALUE=1.8 | - | - | VALUE=1.5 | VALUE=1.4 | VALUE=1.3 | VALUE=1.8 |
| 6 | --env VALUE | - | - | VALUE=1.5 | VALUE=1.4 | VALUE=1.3 | VALUE=1.4 |
| 7 | --env VALUE | - | - | VALUE=1.5 | - | VALUE=1.3 | VALUE=1.3 |
| 8 | - | - | VALUE | VALUE=1.5 | VALUE=1.4 | VALUE=1.3 | VALUE=1.4 |
| 9 | - | - | VALUE | VALUE=1.5 | - | VALUE=1.3 | VALUE=1.3 |
| 10 | - | VALUE | - | VALUE=1.5 | VALUE=1.4 | VALUE=1.3 | VALUE=1.4 |
| 11 | - | VALUE | - | VALUE=1.5 | - | VALUE=1.3 | VALUE=1.3 |
| 12 | --env VALUE | VALUE=1.7 | - | VALUE=1.5 | VALUE=1.4 | VALUE=1.3 | VALUE=1.4 |
| 13 | --env VALUE=1.8 | VALUE=1.7 | - | VALUE=1.5 | VALUE=1.4 | VALUE=1.3 | VALUE=1.8 |
| 14 | --env VALUE=1.8 | - | VALUE=1.6 | VALUE=1.5 | VALUE=1.4 | VALUE=1.3 | VALUE=1.8 |
| 15 | --env VALUE=1.8 | VALUE=1.7 | VALUE=1.6 | VALUE=1.5 | VALUE=1.4 | VALUE=1.3 | VALUE=1.8 |
Understanding precedence results
Result 1: The local environment takes precedence, but the Compose file is not set to replicate this inside the container, so no such variable is set.
Result 2: The env_file attribute in the Compose file defines an explicit value for VALUE so the container environment is set accordingly.
Result 3: The environment attribute in the Compose file defines an explicit value for VALUE, so the container environment is set accordingly.
Result 4: The image's ENV directive declares the variable VALUE, and since the Compose file is not set to override this value, this variable is defined by image
Result 5: The docker compose run command has the --env flag set with an explicit value, and overrides the value set by the image.
Result 6: The docker compose run command has the --env flag set to replicate the value from the environment. Host OS value takes precedence and is replicated into the container's environment.
Result 7: The docker compose run command has the --env flag set to replicate the value from the environment. Value from .env file is selected to define the container's environment.
Result 8: The env_file attribute in the Compose file is set to replicate VALUE from the local environment. Host OS value takes precedence and is replicated into the container's environment.
Result 9: The env_file attribute in the Compose file is set to replicate VALUE from the local environment. Value from .env file is selected to define the container's environment.
Result 10: The environment attribute in the Compose file is set to replicate VALUE from the local environment. Host OS value takes precedence and is replicated into the container's environment.
Result 11: The environment attribute in the Compose file is set to replicate VALUE from the local environment. Value from .env file is selected to define the container's environment.
Result 12: The --env flag has higher precedence than the environment and env_file attributes and is to set to replicate VALUE from the local environment. Host OS value takes precedence and is replicated into the container's environment.
Results 13 to 15: The --env flag has higher precedence than the environment and env_file attributes and so sets the value.