Environment variables precedence in Docker Compose
When you set the same environment variable in multiple sources, there’s a precedence rule used by Compose. It aims to resolve the value for the variable in question.
This page contains information on the level of precedence each method of setting environmental variables takes.
The order of precedence (highest to lowest) is as follows:
- Set using
docker compose run -e
in the CLI - Substituted from your shell
- Set using the
environment
attribute in the Compose file - Use of the
--env-file
argument in the CLI - Use of the
env_file
attribute in the Compose file - Set using an
.env
file placed at base of your project directory - Set in a container image in the
ENV directive.
Having any
ARG
orENV
setting in aDockerfile
evaluates only if there is no Docker Compose entry forenvironment
,env_file
orrun --env
.
Simple example
In the example below, we set a different value for the same environment variable in an .env
file and with the environment
attribute in the Compose file:
$ cat ./Docker/api/api.env
NODE_ENV=test
$ cat compose.yml
services:
api:
image: 'node:6-alpine'
env_file:
- ./Docker/api/api.env
environment:
- NODE_ENV=production
The environment variable defined with the environment
attribute takes precedence.
$ docker compose exec api node
> process.env.NODE_ENV
'production'
Hard coding variables in container scripts
Executing a command within the container that unconditionally sets a variable value overrules any setting in your
compose.yml
file.For example, in a NodeJS project, if you have a
package.json
entry forscripts.start
, such asNODE_ENV=test
node server.js
, any value set forNODE_ENV
in your Compose file, is ignored when runningnpm run start
within the container.
Advanced example
The following table uses TAG
, 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 TAG
.
The columns Host OS environment
and .env file
is listed only as an illustration lookup. In reality, they don't result in a variable in the container by itself.
Each row represents a combination of contexts where TAG
is set, substituted, or both.
# | docker compose run --env | environment attribute | env_file attribute | Image ENV | Host OS environment | .env file | Result | |
---|---|---|---|---|---|---|---|---|
1 | - | - | - | - | TAG=1.4 | TAG=1.3 | - | |
2 | - | - | - | TAG=1.5 | TAG=1.4 | TAG=1.3 | TAG=1.5 | |
3 | TAG | - | - | TAG=1.5 | TAG=1.4 | TAG=1.3 | TAG=1.4 | |
4 | - | - | TAG | TAG=1.5 | - | TAG=1.3 | TAG=1.3 | |
5 | TAG | - | - | TAG=1.5 | - | TAG=1.3 | TAG=1.3 | |
6 | TAG=1.8 | - | - | TAG=1.5 | TAG=1.4 | TAG=1.3 | TAG=1.8 | |
7 | - | TAG | - | TAG=1.5 | TAG=1.4 | TAG=1.3 | TAG=1.4 | |
8 | TAG | TAG=1.7 | - | TAG=1.5 | TAG=1.4 | TAG=1.3 | TAG=1.4 | |
9 | TAG=1.8 | TAG=1.7 | - | TAG=1.5 | TAG=1.4 | TAG=1.3 | TAG=1.8 | |
10 | TAG=1.8 | - | TAG=1.6 | TAG=1.5 | TAG=1.4 | TAG=1.3 | TAG=1.8 | |
11 | TAG=1.8 | TAG=1.7 | TAG=1.6 | TAG=1.5 | TAG=1.4 | TAG=1.3 | TAG=1.8 | |
12 | - | - | TAG=1.6 | TAG=1.5 | TAG=1.4 | - | TAG=1.6 | |
13 | - | TAG=1.7 | - | TAG=1.5 | TAG=1.4 | - | TAG=1.7 |