Understanding the Differences Between Docker ENV and RUN Export: A Simple Guide
In the world of Docker, it is very important to manage environment
variables well. This helps us build strong applications. In this
article, we will look at the main differences between ENV
and RUN export
in Dockerfiles. Both are used to set
environment variables for Docker containers. Knowing these differences
helps us choose the right method for our needs. We will explore the
details of each method, where they work best, and how to manage
environment variables well in our Docker applications.
In this chapter, we will talk about these solutions:
- Solution 1 - Understanding Docker
ENV
- Solution 2 - Understanding
RUN
andexport
- Solution 3 - Using
ENV
to Set Environment Variables - Solution 4 - Using
RUN export
in Dockerfile - Solution 5 - The Scope of
ENV
vsRUN export
- Solution 6 - Best Practices for Environment Variables in Docker
For more reading on related Docker topics, we can check our articles on how to change Docker images and the difference between RUN and CMD.
Solution 1 - Understanding Docker ENV
The ENV
instruction in a Dockerfile helps us set
environment variables. These variables will last during the container’s
runtime. This is important for adjusting application settings and other
environment-specific values. We can do this without putting them
directly in our application code.
Key Features of Docker ENV
- Persistence: When we set variables with
ENV
, they stay available in all layers built after this instruction. They are also available in the running container. - Scope: Any process running in the container can access these environment variables.
- Default Values: We can set default values for our application. This is helpful for settings that may change based on the environment, like development, testing, or production.
Syntax
The basic way to use the ENV
instruction looks like
this:
ENV <key> <value>
We can also set multiple environment variables in one line:
ENV VAR1=value1 VAR2=value2
Example
Here is an example of a Dockerfile that uses the ENV
instruction:
FROM node:14
# Set environment variables
ENV NODE_ENV=production
ENV PORT=3000
# Create app directory
WORKDIR /usr/src/app
# Install app dependencies
COPY package*.json ./
RUN npm install --only=production
# Bundle app source
COPY . .
EXPOSE $PORT
CMD ["node", "server.js"]
In this example, we set the NODE_ENV
variable to
production
. This may change how the application works, like
enabling or disabling some features. The PORT
variable is
set to 3000
. We can use this in our application to listen
for incoming requests.
Accessing ENV Variables
In our application, we can access these environment variables using the standard methods for our programming language. For example, in Node.js, we can do it like this:
const port = process.env.PORT || 8080;
Benefits of Using ENV
Using ENV
in our Dockerfile helps us follow best
practices by:
- Making our application more portable, since we avoid hardcoded values.
- Making it easier to manage configurations in different environments.
- Improving security by not showing sensitive settings directly in our code.
For more information about handling environment variables in Docker, we can check out how to pass environment variables.
Solution 2 - Understanding RUN and export
In Docker, we use the RUN
instruction to run commands
while we build the image. This helps us install packages, set up files,
and do other tasks needed for our application. When we use the
RUN
instruction, it makes a new layer in the Docker image
with the results of the command we ran.
The RUN instruction
The way we write the RUN
instruction can be like
this:
RUN command
Or we can use the shell form:
RUN ["executable", "param1", "param2"]
For example, if we want to install curl
in a
Debian-based image, we write:
FROM debian:latest
RUN apt-get update && apt-get install -y curl
Environment Variables with RUN
If we need to set an environment variable for just the
RUN
command, we can use the export
command in
a shell. But these variables will not stay in the final image. They only
exist while that specific RUN
command is running.
Here’s an example:
FROM ubuntu:latest
RUN export MY_VAR="Hello World" && echo $MY_VAR
In this case, MY_VAR
gets set and printed during the
build, but it will not be there in the final image. This shows that
export
is good for temporary variables during the build,
but it does not change the environment of the running container.
Differences from ENV
On the other hand, the ENV
instruction in Docker is used
to set environment variables that stay in the container after we create
it. For example:
FROM ubuntu:latest
ENV MY_VAR="Hello World"
This makes MY_VAR
an environment variable for the whole
time the container runs. We can access it in any later RUN
,
CMD
, or when we start the container.
Summary of RUN and export
- Purpose of RUN: Run commands while we build the image.
- Temporary Variables: Using
export
in aRUN
command does not keep the variable after the command ends. - Persistent Variables: Use
ENV
to make environment variables that stay in the container.
For more information on the difference between RUN
and
CMD
, we can look at this detailed
explanation. It is important for us to understand the differences
between RUN
and ENV
to manage environment
variables in our Docker images well.
Solution 3 - Using ENV to Set Environment Variables
We use the ENV
instruction in a Dockerfile to set
environment variables. These variables will be available in the
container while building and running. This instruction helps us define
variables. We can use them in later instructions or access them in the
running apps inside the container.
Syntax
The basic way to use ENV
is:
ENV <key>=<value>
We can also set many environment variables in one ENV
instruction:
ENV <key1>=<value1> <key2>=<value2>
Example
Here is a simple example to show how we can use ENV
in a
Dockerfile:
# Use an official Python runtime as a parent image
FROM python:3.9-slim
# Set environment variables
ENV APP_HOME=/usr/src/app
ENV PYTHONUNBUFFERED=1
# Set the working directory
WORKDIR $APP_HOME
# Copy the current directory contents into the container at $APP_HOME
COPY . .
# Install dependencies
RUN pip install -r requirements.txt
# Run the application
CMD ["python", "app.py"]
Explanation
- Environment Variables: In this example, we define
two environment variables. They are
APP_HOME
andPYTHONUNBUFFERED
. TheAPP_HOME
variable tells where the app will be. ThePYTHONUNBUFFERED
is set to1
so that Python outputs go straight to the terminal without delay. - Usage in Dockerfile: The
WORKDIR
instruction uses theAPP_HOME
variable. This makes the Dockerfile cleaner and easier for us to keep. - Accessing Environment Variables: Apps running in
the container can reach these variables. They can use the normal ways
for the programming language they use. For example, in Python, we get
the
APP_HOME
variable by usingos.environ.get('APP_HOME')
.
Benefits of Using ENV
- Configuration Management: Environment variables help us manage settings for different situations like development, testing, or production without changing the code.
- Security: We can set sensitive data like API keys as environment variables. This is safer than putting them directly in our code.
- Docker Best Practices: Using
ENV
helps us follow Docker best practices. It keeps the Dockerfile clear and easy to read. This allows better layering and caching when we build.
For more reading on Dockerfile instructions, check this resource.
Using ENV
well can make our Docker images more flexible
and easy to manage. This helps our apps run smoothly in all
environments.
Solution 4 - Using RUN export in Dockerfile
In Docker, we use the RUN
instruction to run commands in
a new layer on top of the current image. This saves the results. This is
different from ENV
, which sets environment variables that
stay for the whole time the container runs. When we use
RUN export
, we need to know its limits and what it can
do.
How RUN export
Works
When we use RUN
to run a command, we can set environment
variables for that command with export
. But these variables
will not be available in later layers or when the container runs. Here
is an example of using RUN
with export
in a
Dockerfile:
FROM ubuntu:20.04
# Using RUN to set a temporary environment variable
RUN export MY_VAR="Hello World" && \
echo $MY_VAR
# Check that MY_VAR is not available in the next RUN instruction
RUN echo $MY_VAR # This will not print "Hello World"
In this example, we set and show MY_VAR
successfully in
the first RUN
command. But we cannot access it in the next
command. This happens because of how Docker manages layers.
Best Practices for Using
RUN export
Temporary Variables: We should use
RUN export
for temporary variables that we only need for that command. If we want environment variables for the whole container, we should use theENV
instruction instead.Chaining Commands: We can link multiple commands using
&&
. But remember, once theRUN
instruction finishes, any exported variables will be gone. For example:RUN export MY_VAR="Hello" && \ echo $MY_VAR && \ echo "This is a Dockerfile example"
Avoid Confusion: We must not mix up
RUN export
withENV
. TheENV
command will keep the environment variable for all later layers and commands in the container.
Common Use Cases
Installing Packages: If we need to install packages that need special environment variables for a short time, we can use
RUN export
:RUN export DEBIAN_FRONTEND=noninteractive && \ apt-get update && \ apt-get install -y some-package
Build Scripts: Running build scripts that need specific settings can use
RUN export
:RUN export BUILD_ENV=production && \ ./build.sh
Conclusion
Using RUN export
in Dockerfiles helps us set temporary
environment variables for certain commands. But for environment
variables that need to last all the time the container runs, we should
use ENV
. Knowing the limits of RUN export
helps us manage environment variables better in our Docker files. For
more on environment variables in Docker, check out this guide
on passing environment variables.
Solution 5 - The Scope of ENV vs RUN export
We need to understand the scope of environment variables set with
ENV
and those set with RUN export
. This is
important when we work with Dockerfiles. The difference in scope can
change how our application works during the build and runtime.
Scope of ENV
Lasts Across Layers:
When we define an environment variable using the
ENV
instruction in our Dockerfile, it stays across all layers of the Docker image. This means any command in later layers can use the variable.Example:
FROM ubuntu:latest ENV MY_VAR=my_value RUN echo $MY_VAR # This will show 'my_value'
At Container Runtime:
Environment variables set with
ENV
are available when the container runs. This helps us configure our application using these environment variables.Example:
FROM ubuntu:latest ENV APP_ENV=production CMD ["echo", "$APP_ENV"] # When the container runs, it will show 'production'
Scope of RUN export
Temporary Scope:
The
RUN export
command sets environment variables for the time of the RUN command only. After the command is done, the variable is not available in later layers of the image or in the final container.Example:
FROM ubuntu:latest RUN export TEMP_VAR=temp_value && echo $TEMP_VAR # Shows 'temp_value' RUN echo $TEMP_VAR # This will not show anything
Build Time Only:
We use
RUN export
when we need temporary variables for just one RUN command. It does not change other commands or the container’s runtime environment.Example:
FROM ubuntu:latest RUN export BUILD_VAR=build_value && make build RUN echo $BUILD_VAR # This will not show anything
Summary of Differences
- Persistence:
ENV
variables last across layers and are available when the container runs. ButRUN export
variables are temporary. They only last for the time of the RUN command. - Use Cases:
- We should use
ENV
for setting config values that our application needs at runtime. - We should use
RUN export
for temporary variables needed just during the build phase.
- We should use
By knowing the differences between ENV
and
RUN export
, we can manage environment variables in our
Docker containers. This helps ensure our applications work well during
both build
Solution 6 - Best Practices for Environment Variables in Docker
When we work with Docker, managing environment variables is very important. This helps us create applications that are easy to maintain and secure. Here are some best practices to follow.
Use the ENV Instruction Wisely:
We can use the
ENV
instruction in our Dockerfile to set environment variables needed for our application. This way, the variables are ready when we build and can be used by running containers.Example:
FROM node:14 ENV NODE_ENV=production ENV API_URL=https://api.example.com
Keep Sensitive Data Out of Dockerfiles:
We should not hardcode sensitive information like API keys and passwords in our Dockerfiles. Instead, we can use Docker secrets or environment files to manage this data safely.
We can pass sensitive variables when we run the container using the
--env-file
option:docker run --env-file .env myapp
Use a
.env
File for Local Development:It is good to store environment variables in a
.env
file during local development. This keeps our configuration the same and separate from our code.Example
.env
file:NODE_ENV=development API_URL=http://localhost:3000
Document Environment Variables:
- We should keep clear documentation of all environment variables in our application. This includes what they do, their default values, and any dependencies. This helps new developers and when we come back to the project later.
Avoid Using RUN export:
- Using
RUN export VAR=value
in our Dockerfile is not a good idea. The exported variables only exist for that command. Instead, we should define them with theENV
instruction so they last across layers and during container runtime.
- Using
Use Consistent Naming Conventions:
We need to have a consistent naming convention for our environment variables. This helps us easily see what they do and avoids naming problems. For example, we can use uppercase letters with underscores:
DATABASE_URL REDIS_HOST
Limit the Scope of Environment Variables:
- We should only pass the environment variables that our application really needs. This makes it safer and prevents sensitive information from being exposed.
Use Docker Compose for Multi-Container Applications:
For applications with many containers, we can use Docker Compose to manage environment variables better. We can define them in the
docker-compose.yml
file or use an external.env
file.Example
docker-compose.yml
:version: "3" services: web: image: myapp env_file: - .env
Version Control for Environment Configuration:
- If we are using a
.env
file, we should think about excluding it from version control (like using.gitignore
). We can also provide a sample file (like.env.example
) that shows the needed environment variables.
- If we are using a
By following these best practices, we can make our Docker applications secure and easy to configure and maintain. For more information about managing Docker environment variables, we can check topics like how to pass environment variables in Docker and the difference between RUN and CMD.
Conclusion
In this article, we looked at the differences between Docker
ENV
and RUN export
. We showed how each way
sets up environment variables in Docker containers. It is important to
understand these ideas for good Dockerfile management and container
orchestration.
By using good practices for environment variables in Docker, we can improve our application’s portability and configuration.
For more tips, we can check our guides on how to change Docker images and Docker container linking.
Comments
Post a Comment