[SOLVED] Mastering Environment Variables in Docker Compose: A Simple Guide
In this article, we will look at ways to use environment variables in
Docker Compose. Environment variables are very important. They help us
set up containers in a flexible way. This makes it easier to manage our
applications. When we understand how to use environment variables in our
docker-compose.yml
file, we can make our work better. This
also helps our applications work well in different places.
We will talk about these ways to manage environment variables in Docker Compose:
- Solution 1: Defining Environment Variables in
docker-compose.yml
- Solution 2: Using an
.env
File for Environment Variables - Solution 3: Passing Environment Variables from the Host System
- Solution 4: Overriding Environment Variables in Docker Compose
- Solution 5: Accessing Environment Variables in Dockerfile
- Solution 6: Using Variable Substitution in Docker Compose
By the end of this guide, we will understand how to use these techniques. This will help us improve our Docker Compose setup a lot.
For more information on similar topics, you can check how to pass environment variables in Docker or learn about using Docker Compose. Now let’s start with each solution!
Solution 1 - Defining Environment Variables in docker-compose.yml
We can define environment variables directly in our
docker-compose.yml
file. We use the
environment
key under the service settings. This way, we
can set environment variables for the containers while they run.
Here is how we can do it:
version: "3.8"
services:
web:
image: nginx:latest
environment:
- MY_ENV_VAR=some_value
- ANOTHER_VAR=another_value
In this example, the web
service uses the Nginx image.
We define two environment variables: MY_ENV_VAR
and
ANOTHER_VAR
.
More Complex Example
We can also define environment variables using a dictionary format. This makes it easier to read and allows us to use values that have special characters:
version: "3.8"
services:
app:
image: my_app_image
environment:
MY_ENV_VAR: "some_value"
ANOTHER_VAR: "complex value with spaces"
SECRET_KEY: ${SECRET_KEY} # Reference a variable from the host or .env
Important Notes:
- If we reference an environment variable like
SECRET_KEY
, we must make sure it’s defined in our host environment or in an.env
file. - This way is simple and works good for small projects or setups.
For more advanced settings, we can think about using an
.env
file or other ways to pass environment variables. We
can read more about these options in the next solutions below.
Solution 2 - Using an .env File for Environment Variables
Using an .env
file is one easy and common way to manage
environment variables in Docker Compose. This method helps us keep our
docker-compose.yml
tidy and easy to work with.
Steps to Use an .env
File
Create an
.env
File: In our project folder, we need to make a file called.env
. This file will have our environment variables written asKEY=VALUE
.Example of an
.env
file:DB_HOST=db DB_USER=root DB_PASSWORD=secret
Reference the Variables in
docker-compose.yml
: In ourdocker-compose.yml
file, we can use the variables from the.env
file by writing them like this${VARIABLE_NAME}
.Example of a
docker-compose.yml
:version: "3.8" services: db: image: mysql:latest environment: MYSQL_ROOT_PASSWORD: ${DB_PASSWORD} MYSQL_DATABASE: mydatabase ports: - "3306:3306" app: image: myapp:latest environment: DATABASE_URL: mysql://${DB_USER}:${DB_PASSWORD}@${DB_HOST}/mydatabase depends_on: - db
Start Your Services: We can run this command in the terminal to start our Docker Compose services. Docker Compose will find the environment variables in the
.env
file.docker-compose up -d
Benefits of Using an
.env
File
- Separation of Concerns: It keeps our environment settings separate from the app code.
- Easy to Manage: It makes managing environment variables easier, especially when applications get complex.
- Version Control: We can add the
.env
file to our version control system. But we should keep it out of public repositories for safety.
Best Practices
- Exclude Sensitive Data: We must make sure to not
put sensitive data in version control. We can add the
.env
file to our.gitignore
. - Use Default Values: It is good to provide default
values in our
docker-compose.yml
for better fallback options. - Document Your Variables: It helps to write down
what each variable is for in our
.env
file for later.
Using an .env
file for environment variables in Docker
Compose makes our setup easier and improves security and maintenance.
For more tips on Docker Compose, we can check this article on how
to pass environment variables.
Solution 3 - Passing Environment Variables from the Host System
We can pass environment variables from our host system to our Docker
containers defined in docker-compose.yml
. This way, we can
use existing environment variables on our host. It also helps keep
sensitive data, like passwords or API keys, out of our configuration
files.
Using
Environment Variables in docker-compose.yml
To pass environment variables from our host system, we can reference
them in our docker-compose.yml
file using the
${VARIABLE_NAME}
format. Let’s see how to do it:
Define the Environment Variable on the Host: First, we need to set the environment variable in our terminal or in our shell configuration file, like
.bashrc
or.zshrc
. For example:export MY_ENV_VAR="SomeValue"
Reference the Environment Variable in
docker-compose.yml
: Next, we use the variable in ourdocker-compose.yml
file like this:version: "3.8" services: my_service: image: my_image environment: - MY_ENV_VAR=${MY_ENV_VAR}
Run Docker Compose: When we run
docker-compose up
, Docker will automatically use the value ofMY_ENV_VAR
from our host in the container.
Example
Here is a full example that shows this process:
Set the Environment Variable:
export DATABASE_URL="mysql://user:password@localhost:3306/mydb"
docker-compose.yml Configuration:
version: "3.8" services: db: image: mysql:5.7 environment: - MYSQL_ROOT_PASSWORD=root - MYSQL_DATABASE=mydb - DATABASE_URL=${DATABASE_URL} ports: - "3306:3306"
In this example, the DATABASE_URL
environment variable
from the host will go into the db
service when we run
docker-compose up
.
Important Notes
- If we do not set the variable on the host, Docker Compose will send
an empty string to the container. We can also give a default value like
this:
${MY_ENV_VAR:-default_value}
. - We should make sure our environment variables do not clash with existing variables in the container.
- For sensitive info, we can use Docker secrets or an external tool for secrets management instead of passing them through environment variables.
For more details on managing environment variables in Docker, we can check out this guide.
Solution 4 - Overriding Environment Variables in docker-compose
In Docker Compose, we can easily change environment variables that we
set in our docker-compose.yml
file. This is very helpful
when we want to adjust the setup for different places like development,
testing, or production without changing the main setup.
To change environment variables in Docker Compose, we can use these methods:
Using the command line: We can set environment variables right in the command line when we run the
docker-compose
command. We do this by adding the variable before the command.MY_ENV_VAR=value docker-compose up
In our
docker-compose.yml
, we can useMY_ENV_VAR
like this:version: "3" services: my_service: image: my_image environment: - MY_ENV_VAR=${MY_ENV_VAR}
Using an
.env
file: We can use the.env
file to set default values for environment variables. But if we set the same variable in the command line, it will take priority over the one in the.env
file.We should create a
.env
file in the same folder as ourdocker-compose.yml
:MY_ENV_VAR=default_value
Then, we can reference it in our
docker-compose.yml
:version: "3" services: my_service: image: my_image environment: - MY_ENV_VAR
To change it, we just run:
MY_ENV_VAR=new_value docker-compose up
Using
docker-compose.override.yml
: Docker Compose looks for a file calleddocker-compose.override.yml
. This file can change or override settings from the maindocker-compose.yml
. For example:docker-compose.override.yml
:version: "3" services: my_service: environment: - MY_ENV_VAR=new_override_value
When we run
docker-compose up
, Docker Compose will combine the setups and use the new value ofMY_ENV_VAR
.Specifying values in a specific Compose file: We can also make several Compose files and say which one to use with the
-f
option. For example, we might have adocker-compose.prod.yml
for production settings and environment variables:version: "3" services: my_service: image: my_image environment: - MY_ENV_VAR=prod_value
We can run it with:
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up
In short, we can change environment variables in Docker Compose using
the command line, an .env
file, a separate override YAML
file, or by using multiple Compose files. This gives us the freedom to
manage different setups easily. For more help on using environment
variables in Docker Compose, check this
link.
Solution 5 - Accessing Environment Variables in Dockerfile
In Docker, we need to access environment variables in a Dockerfile.
This is important for setting up our application and changing how it
works during the build. We can define these environment variables in the
Dockerfile with the ENV
command. Then, we can use them in
our application when it runs.
Defining Environment Variables
To define an environment variable in a Dockerfile, we use this format:
ENV VARIABLE_NAME=value
For example, if we want to set a variable called APP_ENV
to production
, we add this line to our Dockerfile:
ENV APP_ENV=production
Accessing Environment Variables
After we define environment variables in the Dockerfile, we can access them in our application code using methods specific to the programming language. For example:
- In a Node.js application:
const appEnv = process.env.APP_ENV; // Accessing the APP_ENV variable
console.log(`The application is running in ${appEnv} mode.`);
- In a Python application:
import os
= os.getenv('APP_ENV') # Accessing the APP_ENV variable
app_env print(f'The application is running in {app_env} mode.')
Using Build Arguments
If we want to pass changing values when we build, we can use build
arguments with the ARG
command. For example:
ARG APP_VERSION
ENV VERSION=${APP_VERSION}
Then, we can build our Docker image with this command:
docker build --build-arg APP_VERSION=1.0 -t my-app .
This command sets the VERSION
environment variable in
the Docker image based on the APP_VERSION
we provide while
building.
Best Practices
Combine ENV and ARG: We should use
ARG
for values we need at build time andENV
for values we need when the application runs. This helps us keep our Dockerfile clean.Document Variables: We should add comments about our environment variables in the Dockerfile to explain what they do.
Avoid Sensitive Information: We must not put sensitive information like passwords directly in the Dockerfile. We can use a secrets management tool or pass them as environment variables when the application runs.
Example Dockerfile
Here is a complete example of a Dockerfile that shows how to use environment variables:
# Use a base image
FROM python:3.9-slim
# Set environment variables
ENV APP_ENV=production
ENV VERSION=1.0
# Set a working directory
WORKDIR /app
# Copy application files
COPY . .
# Install dependencies
RUN pip install -r requirements.txt
# Command to run the application
CMD ["python", "app.py"]
In this example, the Dockerfile sets environment variables for the application. It uses them in the application code. This helps us make our Docker images more flexible and easy to configure.
For more details about using Dockerfiles, we can check this article on Dockerfile configuration.
Solution 6 - Using Variable Substitution in docker-compose
We can use variable substitution in docker-compose
to
define values that change. This means we can use environment variables
or other variables in our docker-compose.yml
file. This
feature helps us be more flexible. It lets us manage different
environments like development, testing, and production easily.
Basic Syntax
In a docker-compose.yml
file, we can use variable
substitution by putting the variable name in ${}
. For
example:
version: "3.8"
services:
web:
image: ${WEB_IMAGE:-myapp:latest} # Default is 'myapp:latest' if WEB_IMAGE is not set
ports:
- "${WEB_PORT:-80}:80" # Default is port 80 if WEB_PORT is not set
Defining Variables
We can define variables in a few ways:
Environment Variables: We can set environment variables in our shell before we run
docker-compose
:export WEB_IMAGE=myapp:production export WEB_PORT=8080 docker-compose up
.env File: We can create a
.env
file in the same folder as ourdocker-compose.yml
. The file can have key-value pairs for our variables:WEB_IMAGE=myapp:production WEB_PORT=8080
docker-compose
reads this file automatically when it runs.Inline Variables: We can also give variables inline when we run
docker-compose
:WEB_IMAGE=myapp:production WEB_PORT=8080 docker-compose up
Using Variable Substitution
When we use variable substitution, the syntax
${VARIABLE_NAME}
lets us use the defined environment
variables directly in the docker-compose.yml
. We can use
this for images, ports, volumes, and other options that support
substitution.
Here is an example to show variable substitution in a full service definition:
version: "3.8"
services:
app:
image: ${APP_IMAGE:-myapp:latest}
environment:
- NODE_ENV=${NODE_ENV:-development}
ports:
- "${APP_PORT:-3000}:3000"
volumes:
- ${APP_DATA_DIR:-./data}:/data
In this example:
- The
APP_IMAGE
variable decides which image to use for the app. - The
NODE_ENV
variable sets the environment variable inside the container. - The
APP_PORT
variable allows us to change the port. - The
APP_DATA_DIR
variable lets us set a data folder that can be mapped to the container.
Important Notes
- If we do not define a variable, we can give a default value using
${VARIABLE:-default_value}
. - Be careful with variable names to not conflict with Docker Compose internal variables.
- For more details on
docker-compose
variable substitution, you can check the official docker-compose documentation.
By using variable substitution in docker-compose
, we can
make our configuration more flexible and easier to manage. It helps us
adapt to different deployment situations In conclusion, we have looked
at different ways to use environment variables in Docker Compose. We
talked about defining them directly in docker-compose.yml
.
We also discussed using an .env
file and passing them from
the host system.
Knowing these methods helps us manage our containerized apps better. It also helps us keep our settings clean and flexible.
For more tips on Docker, you can check our guides on how to manage Docker Compose and the importance of environment variables in Docker.
Comments
Post a Comment