The .env
file serves as a mechanism to set environment variables. Sometimes, it’s necessary to ensure these values can be accessed within the containers. At other times, it’s crucial to restrict these variables to the Docker Compose file only.
Upon examining an issue with our product, I discovered that the approach to provide variables to a Compose file differs from the strategies used to pass environment variables to containers. Let’s explore the possible solutions.
Passing environment variables to docker container
Environment variables can be passed to Docker containers in several ways. One method to make certain that variables are accessible within the container is by utilizing the env_file
option in the Docker Compose file.
Consider the following scenario: I have a Docker Compose file and a .env
file. The Docker Compose file includes two variables: version
and password_redis
, with their values specified in the .env
file.
docker-compose.yml
version: "3.7"
name: sample-project
services:
redis:
env_file: .env
container_name: redis-service
image: redis:${version}
command: redis-server --requirepass ${password_redis} --protected-mode no
.env
password_redis=Test@123
version=6.2.4
After starting the container and inspecting it using the docker inspect
command, it’s evident that the container can access the two variables defined in the .env
file.
"Env": [
"version=6.2.4",
"password_redis=Test@123",
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"GOSU_VERSION=1.12",
"REDIS_VERSION=6.2.4",
"REDIS_DOWNLOAD_URL=http://download.redis.io/releases/redis-6.2.4.tar.gz",
"REDIS_DOWNLOAD_SHA=ba32c406a10fc2c09426e2be2787d74ff204eb3a2e496d87cff76a476b6ae16e"
]
By executing the docker-compose config
command, it’s also observable that these variables are transmitted to the containers as environment variables.
❯ docker compose config
name: sample-project
services:
redis:
command:
- redis-server
- --requirepass
- Test@123
- --protected-mode
- "no"
container_name: redis-service
environment:
password_redis: Test@123
version: 6.2.4
image: redis:6.2.4
networks:
default: null
networks:
default:
name: sample-project_default
Passing environment variables to a docker compose file
If you remove the env_file
option from the Docker Compose file, the environment variables defined in the .env
file will not be passed into the container.
docker-compose.yml
version: "3.7"
name: sample-project
services:
redis:
container_name: redis-service
image: redis:${version}
command: redis-server --requirepass ${password_redis} --protected-mode no
Here’s how you can verify this:
-
Start the container:
docker-compose up -d
-
Inspect the container:
docker inspect <container_id>
. Replace<container_id>
with the ID of your container. In the output, you will not see the environment variables defined in the.env
file.
output
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"GOSU_VERSION=1.12",
"REDIS_VERSION=6.2.4",
"REDIS_DOWNLOAD_URL=http://download.redis.io/releases/redis-6.2.4.tar.gz",
"REDIS_DOWNLOAD_SHA=ba32c406a10fc2c09426e2be2787d74ff204eb3a2e496d87cff76a476b6ae16e"
]
- Check the Docker Compose configuration:
docker-compose config
. In the output, you will see that the variables from the.env
file have been replaced in the Docker Compose file, but they are not set as environment variables in the container. This is because theenv_file
option is what tells Docker Compose to pass the variables as environment variables to the container. Without it, the variables are only used for substitution in the Docker Compose file.
Output
❯ docker compose config
name: sample-project
services:
redis:
command:
- redis-server
- --requirepass
- Test@123
- --protected-mode
- "no"
container_name: redis-service
image: redis:6.2.4
networks:
default: null
networks:
default:
name: sample-project_default