Docker ENV vs ARG Explained: Key Differences to Know

When working with Docker, two essential instructions, ENV and ARG, are often used to handle variables in your Dockerfile. While they may seem similar, they serve different purposes. Let’s dive into their differences, use cases, and best practices!


Overview

FeatureARGENV
ScopeBuild-timeRun-time
Default ValueYes (via ARG name=default_value)Yes (via ENV name=value)
AccessibilityAvailable only during buildAvailable during build and run
PersistencyNot persisted in the final imagePersisted in the final image

What is ARG?

The ARG instruction is used to define build-time variables. These variables are available only during the build process of the Docker image and cannot be accessed once the image is running.

Key Features of ARG:

  • Used for passing build-time information like application versions, flags, or secrets.

  • Can have a default value.

  • Can be overridden via the --build-arg flag when running docker build.

Example: Using ARG

ARG APP_VERSION=1.0.0
FROM alpine:${APP_VERSION}

RUN echo "Building with version ${APP_VERSION}"

To build the image with a custom version:

docker build --build-arg APP_VERSION=3.15 -t my-alpine .

What is ENV?

The ENV instruction is used to define environment variables that are available both during the image build process and at runtime. These variables are persisted in the final image.

Key Features of ENV:

  • Used to configure application behavior or pass runtime variables.

  • Can be overridden at runtime with the docker run -e flag or Docker Compose.

  • Useful for defining default values for environment variables.

Example: Using ENV


FROM alpine:3.15

ENV APP_ENV=production

RUN echo "Environment is set to ${APP_ENV}"

CMD ["sh"]

To override the variable at runtime:

docker run -e APP_ENV=development my-alpine

Comparison: When to Use ARG vs ENV

Use CaseInstruction to Use
Pass secrets during buildARG
Specify application versionARG
Configure runtime application behaviorENV
Define default runtime variablesENV
Variables not needed after buildARG

Key Notes and Best Practices

  1. Security:

    • Avoid using ENV for sensitive information (e.g., passwords or API keys), as they persist in the image and can be inspected.

    • Use ARG for sensitive build-time secrets and tools like Docker BuildKit for better security.

  2. Default Values:
    Both ARG and ENV allow default values, but ARG defaults are accessible only during the build stage, while ENV defaults persist through runtime.

  3. Combination:
    You can combine ARG and ENV to define runtime environment variables using build-time arguments:

     ARG APP_ENV=production
     ENV APP_ENV=${APP_ENV}
    
  4. Overriding:

    • ARG values can be overridden at build time with --build-arg.

    • ENV values can be overridden at runtime with docker run -e.


Conclusion

In summary:

  • Use ARG for build-time variables (temporary use).

  • Use ENV for runtime variables (persistent use).

Understanding when to use each is essential for writing efficient and secure Dockerfiles. Keep these distinctions in mind, and you'll be crafting Dockerfiles like a pro