Skip to main content

[SOLVED] docker ENV vs RUN export - docker

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 and export
  • Solution 3 - Using ENV to Set Environment Variables
  • Solution 4 - Using RUN export in Dockerfile
  • Solution 5 - The Scope of ENV vs RUN 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 a RUN 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 and PYTHONUNBUFFERED. The APP_HOME variable tells where the app will be. The PYTHONUNBUFFERED is set to 1 so that Python outputs go straight to the terminal without delay.
  • Usage in Dockerfile: The WORKDIR instruction uses the APP_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 using os.environ.get('APP_HOME').

Benefits of Using ENV

  1. Configuration Management: Environment variables help us manage settings for different situations like development, testing, or production without changing the code.
  2. Security: We can set sensitive data like API keys as environment variables. This is safer than putting them directly in our code.
  3. 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

  1. 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 the ENV instruction instead.

  2. Chaining Commands: We can link multiple commands using &&. But remember, once the RUN instruction finishes, any exported variables will be gone. For example:

    RUN export MY_VAR="Hello" && \
        echo $MY_VAR && \
        echo "This is a Dockerfile example"
  3. Avoid Confusion: We must not mix up RUN export with ENV. The ENV 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

  1. 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'
  2. 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

  1. 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
  2. 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. But RUN 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.

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.

  1. 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
  2. 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
  3. 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
  4. 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.
  5. 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 the ENV instruction so they last across layers and during container runtime.
  6. 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
  7. 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.
  8. 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
  9. 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.

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