Ways to Set Environment Variables With Docker Compose
Docker Compose is a tool for defining and running multi-container Docker applications. It defines the services that make up an application, the networks they connect to, and the environment variables they need to run.
With Docker Compose, there are multiple ways to set environment variables in containers: the Compose file, or the CLI. Each method is subject to environment variable precedence.
Tip
Don’t use environment variables to pass sensitive information, such as passwords, in to your containers. Use secrets instead.
Compose file
Substitute with an .env file
An .env file in Docker Compose is a text file used to define environment variables that should be made available to Docker containers when running docker compose up. This file typically contains key-value pairs of environment variables, and it centralizes configuration in one place. The .env file is useful when multiple environment variables need storing.
The .env file is the default method for setting environment variables in your containers. The .env file should be placed at the root of the project directory next to your compose.yaml file. For more information on formatting an environment file, see Syntax for environment files.
Below is a simple example:
$ cat .env
TAG=v1.5
$ cat compose.yml
services:
web:
image: "webapp:${TAG}"When docker compose up runs, the web service defined in the Compose file interpolates in the image webapp:v1.5 which was set in the .env file. Verify this with the config command, which prints the resolved application config to the terminal:
$ docker compose config
services:
web:
image: 'webapp:v1.5'Additional information
-
As of Docker Compose version 2.24.0, the
.envfile can be optional via theenv_fileattribute. Whenrequiredis set tofalseand the.envfile is missing, Compose silently ignores the entry.env_file: - path: ./default.env required: true # default - path: ./override.env required: false -
An environment variable defined in the
.envfile can be referenced directly incompose.ymlwith theenvironmentattribute. For example, if.envcontainsDEBUG=1andcompose.ymllooks like this:services: webapp: image: my-webapp-image environment: - DEBUG=${DEBUG}Docker Compose replaces
${DEBUG}with the value from the.envfile -
Multiple
.envfiles can be listed incompose.ymlwith theenv_fileattribute. Docker Compose reads them in the order specified. If the same variable is defined in multiple files, the last definition takes precedence:services: webapp: image: my-webapp-image env_file: - .env - .env.override -
The
.envfile can live outside the project root. Use one of the following methods so Compose can navigate to it: -
Values in your
.envfile can be overridden from the command line by usingdocker-compose up -e. -
Your
.envfile can be overridden by another.envif it is substituted with--env-file.
Important
Substitution from
.envfiles is a Docker Compose CLI feature.It is not supported by Swarm when running
docker stack deploy.
Use the environment attribute
Environment variables can be set directly in the Compose file without an .env file, with the environment attribute in compose.yml. It works in the same way as docker run -e VARIABLE=VALUE ...
web:
environment:
- DEBUG=1See environment attribute for more examples on how to use it.
Additional information
-
Omit the value to pass environment variables from the shell straight through to the containers. It works in the same way as
docker run -e VARIABLE ...:web: environment: - DEBUGThe value of the
DEBUGvariable in the container is taken from the value for the same variable in the shell in which Compose is run. Note that in this case no warning is issued if theDEBUGvariable in the shell environment is not set. -
Interpolation is also available.
web: environment: - DEBUG=${DEBUG}The result is similar to the one above but Compose warns if the
DEBUGvariable is not set in the shell environment.
Use the env_file attribute
The env_file attribute attaches multiple .env files in a Compose application. It keeps environment variables separate from the main configuration file, so the .env file does not have to sit in the project root.
It works in the same way as docker run --env-file=FILE ....
web:
env_file:
- web-variables.envAdditional information
-
If multiple files are specified, they are evaluated in order and can override values set in previous files.
-
Environment variables declared in the
.envfile cannot then be referenced again separately in the Compose file. -
If both
env_fileandenvironmentare set, variables fromenvironmenttake precedence. -
The paths to your
.envfile, specified in theenv_fileattribute, are relative to the location of yourcompose.ymlfile. -
Values in your
.envfiles can be overridden from the command line by usingdocker compose run -e. -
Your
.envfiles can be overriden by another.envif it is substituted with--env-file. -
As of Docker Compose version 2.24.0, the
.envfile can be optional via therequiredfield. Whenrequiredis set tofalseand the.envfile is missing, Compose silently ignores the entry.env_file: - path: ./default.env required: true # default - path: ./override.env required: false
Substitute from the shell
Existing environment variables can come from the host or from the shell that runs docker compose. Values inject into the Compose configuration at runtime.
For example, suppose the shell contains POSTGRES_VERSION=9.3 and the following configuration is supplied:
db:
image: "postgres:${POSTGRES_VERSION}"When docker compose up runs with this configuration, Compose looks for POSTGRES_VERSION in the shell and substitutes its value. For this example, Compose resolves the image to postgres:9.3 before running the configuration.
If an environment variable is not set, Compose substitutes with an empty string. In the example above, if POSTGRES_VERSION is not set, the value for the image option is postgres:.
Note
postgres:is not a valid image reference. Docker expects either a reference without a tag, likepostgreswhich defaults to the latest image, or with a tag such aspostgres:15.
Important
Values set in the shell environment override those set in the
.envfile, theenvironmentattribute, and theenv_fileattribute. For more information, see Environment variable precedence.
CLI
Substitute with –env-file
Default values for multiple environment variables can live in an environment file and be passed as a CLI argument.
The file can live anywhere and be named appropriately, for example,
This file path is relative to the current working directory where the Docker Compose command is executed. Passing the file path is done using the --env-file option:
docker compose --env-file ./config/.env.dev upAdditional information
-
Useful to temporarily override an
.envfile already referenced incompose.yml. For example production (.env.prod) vs testing (.env.test). In the following example,.envand.env.devset differentTAGvalues.$ cat .env TAG=v1.5 $ cat ./config/.env.dev TAG=v1.6 $ cat compose.yml services: web: image: "webapp:${TAG}"If the
--env-fileis not used in the command line, the.envfile is loaded by default:$ docker compose config services: web: image: 'webapp:v1.5'Passing the
--env-fileargument overrides the default file path:$ docker compose --env-file ./config/.env.dev config services: web: image: 'webapp:v1.6'When an invalid file path is being passed as an
--env-fileargument, Compose returns an error:$ docker compose --env-file ./doesnotexist/.env.dev config ERROR: Couldn't find env file: /home/user/./doesnotexist/.env.dev -
Multiple
--env-fileoptions specify multiple environment files. Docker Compose reads them in order. Later files override earlier ones.$ docker compose --env-file .env --env-file .env.override up -
Specific environment variables can be overridden from the command line when starting containers.
$ docker compose --env-file .env.dev up -e DATABASE_URL=mysql://new_user:new_password@new_db:3306/new_database
Set environment variables with docker compose run –env
Similar to docker run --env, environment variables can be set temporarily with docker compose run --env or docker compose run -e:
$ docker compose run -e DEBUG=1 web python console.pyAdditional information
-
A variable can also be passed from the shell by omitting the value:
$ docker compose run -e DEBUG web python console.pyThe value of the
DEBUGvariable in the container is taken from the value for the same variable in the shell in which Compose is run.
Further resources
- Understand environment variable precedence.
- Set or change predefined environment variables
- Explore best practices
- Understand the syntax and formatting guidelines for environment files