The short answer
In Docker Compose, environment variables can be defined in the form of a list of key-value pairs in a file named [.inline-code].env[.inline-code] located in the root directory of your project:
These variables can then be referenced in the [.inline-code]compose.yaml[.inline-code] file using the variable substitution syntax as follows:
In this example, upon execution of the [.inline-code]docker compose up[.inline-code] command, Docker will substitute the [.inline-code]VERSION[.inline-code] variable with its value, resulting in the pulling of the [.inline-code]webapp:v1.5[.inline-code] image. Note that, if the specified environment variable is not set, Docker will substitute the variable with an empty string.
[#use-custom-env-files] Using custom [.inline-code].env[.inline-code] files [#use-custom-env-files]
Complex projects often include multiple environment files for different purposes, like development (e.g. [.inline-code].env.dev[.inline-code]) and production (e.g. [.inline-code].env.prod[.inline-code]).
In Compose, to use a specific environment file instead of the default [.inline-code].env[.inline-code] file, you can use the [.inline-code]docker compose up[.inline-code] command with the [.inline-code]--env-file[.inline-code] flag as follows:
Where:
- [.inline-code]file[.inline-code] is the absolute or relative path to the environment file.
For example:
Upon execution, the above command will bring up the services set in the [.inline-code]compose.yaml[.inline-code] file and substitute the values of the environment variables from the [.inline-code].env.dev[.inline-code] file.
[#understand-the-variable-precedence] Understanding the order of precedence of environment variables [#understand-the-variable-precedence]
In Compose, the same environment variables can be defined in multiple places, like the shell environment, the default [.inline-code].env[.inline-code] file, or an arbitrary environment file (e.g. [.inline-code].env.prod[.inline-code]).
The order of precedence of these variables is as follows, from the highest to the lowest:
- Shell environment: The variables set in your shell environment take the highest priority. Any variables set in the shell environment will always override those in your environment files.
- Custom [.inline-code].env[.inline-code] file: The environment variables loaded using the [.inline-code]--env-file[.inline-code] flag takes precedence over the default [.inline-code].env[.inline-code] file located at the root of your project's directory.
- Default [.inline-code].env[.inline-code] file: The variables set in the default [.inline-code].env[.inline-code] file have the lowest precedence compared to the above sources.
[#pass-environment-variables-to-containers] Passing environment variables to services [#pass-environment-variables-to-containers]
In Compose, to pass environment variables defined in the [.inline-code].env[.inline-code] file to the various services defined in the [.inline-code]compose.yaml[.inline-code] file, you can use the [.inline-code]environment[.inline-code] property as follows:
Where:
- [.inline-code]name[.inline-code] specifies the name of the environment variable for the container.
- [.inline-code]VARIABLE[.inline-code] specifies the name of the environment variable defined in the [.inline-code].env[.inline-code] file.
For example:
Upon execution of the [.inline-code]docker compose up[.inline-code] command, Compose will start the [.inline-code]web[.inline-code] service and substitute the value of variables [.inline-code]PG_USERNAME[.inline-code], [.inline-code]PG_PASSWORD[.inline-code], and [.inline-code]PG_DATABASE[.inline-code] with the values defined in the [.inline-code].env[.inline-code] file.
You can learn more about PostgreSQL with our article on how to launch a PostgreSQL instance using Docker Compose.
[#easily-recall-syntax-with-ai] Easily retrieve this syntax using Warp AI feature [#easily-recall-syntax-with-ai]
If you’re using Warp as your terminal, you can easily retrieve this syntax using the Warp AI feature:
Entering [.inline-code]docker compose env file[.inline-code] in the AI question input will prompt a human-readable step by step guide including code snippets.
Passing [.inline-code].env[.inline-code] files to services
In Compose, to pass an entire environment file to a service listed in the [.inline-code]compose.yaml[.inline-code] file, you the [.inline-code]env_file[.inline-code] property as follows:
Where:
- [.inline-code]file[.inline-code] is the absolute or relative path to the environment file.
For example:
Upon execution of the [.inline-code]docker compose up[.inline-code] command, Compose will start the [.inline-code]web[.inline-code] service and forward all the environment variables defined in the [.inline-code].env.dev[.inline-code] and [.inline-code].env.prod[.inline-code] files.
Note that since environment files are loaded sequentially, some variables may potentially be overwritten if already defined in preceding files.
Also note that environment variables defined under the [.inline-code]environment[.inline-code] have a higher precedence than the ones passed under the [.inline-code]env_file[.inline-code] property.
[#define-default-variable-values] Defining default values for environment variables [#define-default-variable-values]
In Compose, to assign a default fallback value to an unset or empty environment variable, you can use either one of the following variable substitution expressions:
Where:
- [.inline-code]${VAR:-default}[.inline-code] is used to indicate that the [.inline-code]default[.inline-code] value should be used when the variable [.inline-code]VAR[.inline-code] is empty or unset.
- [.inline-code]${VAR-default}[.inline-code] is used to indicate that the [.inline-code]default[.inline-code] value should be used only when the variable [.inline-code]VAR[.inline-code] is not set.
For example:
Upon execution of the [.inline-code]docker-compose up[.inline-code] command, the environment variables will be set as follows:
- [.inline-code]NGINX_VERSION[.inline-code] is set and non-empty in the [.inline-code].env[.inline-code] file, so the specified value [.inline-code]1.19.5[.inline-code] will be used.
- [.inline-code]DB_URL[.inline-code] is not set in the [.inline-code].env[.inline-code] file, so the default value [.inline-code]mysql://user:password@dbhost/dbname[.inline-code] will be used.
- [.inline-code]CONTAINER_PORT[.inline-code] is set but is empty in the [.inline-code].env[.inline-code] file, so the default value [.inline-code]8080[.inline-code] will be used.
[#enforce-required-variable-values] Enforcing required values for environment variables [#enforce-required-variable-values]
In Compose, to enforce the existence or definition of a required environment variable, which is essential for the proper functioning of the application, you can use either one of the following variable substitution expressions:
Where:
- [.inline-code]${VAR:?error}[.inline-code] will exit with the specified error message [.inline-code]error[.inline-code] if the variable [.inline-code]VAR[.inline-code] is empty or unset.
- [.inline-code]${VAR?error}[.inline-code] will exit with the specified error message [.inline-code]error[.inline-code] only if the variable [.inline-code]VAR[.inline-code] is not set.
For example:
Upon execution of the [.inline-code]docker-compose up[.inline-code] command, the environment variables will be set as follows:
- [.inline-code]TAG[.inline-code] is set and non-empty in the .env file, so the specified value [.inline-code]v1.5[.inline-code] will be used.
- [.inline-code]API_KEY[.inline-code] is not set in the .env file, so the command will exit with the error message [.inline-code]Error: API_KEY is required[.inline-code].
- [.inline-code]CONTAINER_PORT[.inline-code] is set but is empty in the .env file.
- With the colon ([.inline-code]:[.inline-code]) syntax, the empty value for the [.inline-code]CONTAINER_PORT[.inline-code] will be used.
- Without the colon ([.inline-code]:[.inline-code]) syntax, the command will not exit, and the empty value for the [.inline-code]CONTAINER_PORT[.inline-code] will be used.
[#replace-existing-variable-values] Replacing environment variable values [#replace-existing-variable-values]
In Compose, to allow your application to dynamically switch between different configurations based on the availability of specific values, you can overwrite the value of an existing or non-empty environment variable using either one of the following variable substitution expressions:
Where:
- [.inline-code]${VAR:+replacement}[.inline-code] replaces the value of the [.inline-code]VAR[.inline-code] variable with [.inline-code]replacement[.inline-code] if the variable is set and non-empty.
- [.inline-code]${VAR+replacement}[.inline-code] replaces the value of the [.inline-code]VAR[.inline-code] variable with [.inline-code]replacement[.inline-code] only if the variable is set.
For example:
Upon execution of the [.inline-code]docker-compose up[.inline-code] command, the environment variables will be set as follows:
- [.inline-code]TAG[.inline-code] is set and non-empty in the .env file, so the replacement value [.inline-code]latest[.inline-code] will be used.
- [.inline-code]DB_URL[.inline-code] is not set in the .env file, so an empty value will be used for [.inline-code]DB_URL[.inline-code].
- [.inline-code]CONTAINER_PORT[.inline-code] is set but empty in the .env file.
- With the colon ([.inline-code]:[.inline-code]) syntax, the empty value for the [.inline-code]CONTAINER_PORT[.inline-code] will be used.
- Without the colon ([.inline-code]:[.inline-code]) syntax, the replacement value [.inline-code]8080[.inline-code] will be used.