Environment variables play a crucial role in Docker Compose for managing configuration and sensitive data across containerized applications. They provide a flexible way to inject values such as database credentials, API keys, and service ports into containerized environments without hardcoding them into the source code or Docker images.
In Docker Compose, you can define environment variables in multiple ways, such as directly in the compose.yml
file (note: the modern naming convention is compose.yml
rather than docker-compose.yml
), through .env
files, or by passing them during runtime. This flexibility allows for easy configuration management across different deployment environments.
Prerequisites
Before starting, ensure the following:
- Docker and Docker Compose are installed on your system. If not, follow the official Docker installation guide and Docker Compose installation instructions.
- A basic understanding of Docker Compose syntax and YAML configuration files.
- A sample application to test environment variable configurations. You can create a simple Python or Node.js app.
Step 1: Create a Simple Docker Compose File
To begin, let's create a compose.yml
file for a basic web application. This will serve as the foundation for our environment variable configurations.
-
Create a directory for the project:
mkdir docker-compose-env-demo cd docker-compose-env-demo
-
Create a
compose.yml
file:nano compose.yml
Note: The modern naming convention is
compose.yml
rather thandocker-compose.yml
Docker Compose Environment Variables. -
Add the following example configuration:
services: web: image: nginx:latest ports: - "127.0.0.1:${WEB_PORT:-80}:80" environment: - APP_ENV=${APP_ENV:-production}
This configuration sets up an Nginx service and uses environment variables for the WEB_PORT
and APP_ENV
.
Step 2: Define Environment Variables in a .env
File
A .env
file provides a centralized and secure way to define environment variables for Docker Compose.
-
In the same directory as
docker-compose.yml
, create a.env
file:nano .env
-
Add the following variables:
WEB_PORT=8080 APP_ENV=production
-
Save and close the file. Docker Compose automatically loads this file to inject the variables into the services defined in
docker-compose.yml
. -
Test the configuration by running:
docker-compose up
You should see the Nginx service running on port 8080.
Step 3: Set Environment Variables Directly in the Compose File
You can define environment variables directly in the compose.yml
file. This approach is useful for default values or when you want to make the configuration explicit within the file.
-
Modify the
compose.yml
file:services: web: image: nginx:latest ports: - "127.0.0.1:8080:80" environment: - APP_ENV=production - DEBUG=false
-
Run the configuration:
docker compose up
Nginx should run on localhost port 8080 with the
APP_ENV
variable set toproduction
andDEBUG
set tofalse
. -
To verify the environment variables, you can use:
docker compose config
This will show you the resolved configuration, including the set environment variables.
Step 4: Override Variables with Shell Values
Docker Compose allows you to override .env
file values with shell environment variables. This is useful for temporary changes or when deploying to different environments.
-
Set a shell variable:
export WEB_PORT=9090
-
Run Docker Compose:
docker compose up
-
Verify that the container is now binding to port 9090 instead of 8080:
docker compose ps
This demonstrates that shell variables take precedence over
.env
values Docker Compose Environment Variables Precedence. -
To see the resolved configuration, including the overridden values:
docker compose config
Note: Remember to unset the shell variable when you're done to avoid unexpected behavior in future runs:
unset WEB_PORT
Step 5: Secure Sensitive Variables with Docker Secrets
For sensitive data, it's best to avoid using .env
files or plain-text variables in the Compose file. Instead, use Docker Secrets for enhanced security.
-
Create a file for the secret:
echo "supersecretkey" > secret_key.txt
-
Update
compose.yml
to use the secret:services: web: image: nginx:latest ports: - "127.0.0.1:${WEB_PORT:-80}:80" secrets: - app_secret environment: - APP_SECRET_FILE=/run/secrets/app_secret secrets: app_secret: file: ./secret_key.txt
-
Deploy the stack:
docker compose up
The secret is now securely available inside the container at
/run/secrets/app_secret
.
Step 6: Verify Environment Variables in Containers
You can inspect environment variables within a running container for debugging.
-
Find the container's name:
docker ps
-
Use
docker exec
to access the container and list environment variables:docker exec -it <container_name> env
-
Verify that the
APP_ENV
and other variables are correctly set.
Step 6: Verify Environment Variables in Containers
-
Start your Docker Compose project if it's not already running:
docker compose up -d
-
List the running containers:
docker compose ps
This command will show you all the containers defined in your Compose file and their current status.
-
Use
docker compose exec
to access the container and list environment variables:docker compose exec web env
This command runs the
env
command inside theweb
service container, listing all environment variables Docker Compose Run. -
To verify specific variables, you can use grep:
docker compose exec web env | grep APP_ENV
-
For more detailed inspection, you can start a shell inside the container:
docker compose exec web sh
Once inside the container, you can run commands to inspect the environment or your application's configuration.
-
To check if your application is correctly using the environment variables, you might need to inspect application logs:
docker compose logs web
Step 7: Debug Common Issues
When working with environment variables in Docker Compose, you might encounter some common issues.
-
Variable Not Substituting:
- Ensure variables are correctly referenced in
compose.yml
using${VARIABLE_NAME}
syntax. - Use the
docker compose config
command to check if variables are being interpolated correctly.
- Ensure variables are correctly referenced in
-
Shell Variables Not Loading:
- Confirm that
export VARIABLE=value
is used and the terminal session has the variables. - Remember that shell variables are only available in the current session. For persistence, add them to your shell's configuration file (e.g.,
.bashrc
or.zshrc
).
- Confirm that
-
.env
File Not Loaded:- Verify that the
.env
file is in the same directory as thecompose.yml
. - Check file permissions to ensure Docker can read the
.env
file. - Use the
--env-file
option to specify a different.env
file location:docker compose --env-file ./config/.env.dev up
.
- Verify that the
-
Variable Precedence Issues:
- Understand the order of precedence: Compose file > Shell environment >
.env
file . - Use
docker compose config
to see the final resolved configuration.
- Understand the order of precedence: Compose file > Shell environment >
-
Sensitive Data Exposure:
- Avoid putting sensitive data directly in
compose.yml
or.env
files. - Use Docker secrets for sensitive information, especially in production environments.
- Avoid putting sensitive data directly in
-
Unexpected Default Values:
- When using variable substitution with default values (e.g.,
${VARIABLE:-default}
), ensure the default value is appropriate for your use case. - Be aware that an empty string is considered a set value, so
${VARIABLE:-default}
will use the empty string ifVARIABLE
is set to an empty string.
- When using variable substitution with default values (e.g.,
Conclusion
This tutorial demonstrated how to set and use environment variables in Docker Compose using .env
files, direct definitions, runtime overrides, and secrets for sensitive data. Proper management of environment variables enhances the security and maintainability of containerized applications, enabling better configuration practices.
For advanced scenarios, refer to the Docker Compose documentation for more details.