How do environment variables and ARG differ in a Dockerfile?
Understand how ARG build-time variables differ from ENV runtime variables in a Dockerfile, the ARG-to-ENV bridge pattern, and why secrets must not use ARG.
Expected Interview Answer
ARG defines build-time variables that are only available while the image is being built and are not present in the running container, whereas ENV defines environment variables that are baked into the image and remain available to processes inside the running container.
ARG values are passed with --build-arg and can be referenced by instructions during the build, but they disappear once the build finishes. ENV values persist in the image metadata, are inherited by every layer after they are set, and are visible to the application at runtime. A common pattern is to accept an ARG and use it to set an ENV so a build-time choice becomes a runtime default. Importantly, ARG should never carry secrets because build args can be exposed in image history.
- ARG parameterizes builds without affecting runtime
- ENV provides runtime configuration to the app
- ARG can be overridden per build with --build-arg
- ENV can be overridden at run time with -e
- Combining ARG into ENV bridges build-time and runtime config
AI Mentor Explanation
ARG is like the net-practice conditions a team sets up before a match — useful only while preparing and packed away before play starts. ENV is like the rules printed on the match sheet that stay in force throughout the game, guiding every over the players actually bowl on the field.
Step-by-Step Explanation
Step 1
Declare an ARG
Use ARG NAME[=default] before it is referenced; it is only in scope during the build.
Step 2
Pass a value at build
Override with docker build --build-arg NAME=value; unset args fall back to their default.
Step 3
Declare an ENV
Use ENV KEY=value; it is written into image metadata and persists in the running container.
Step 4
Bridge ARG into ENV
Set ENV VERSION=$VERSION from an ARG so a build choice becomes a runtime default.
Step 5
Override ENV at run time
Use docker run -e KEY=value to change the value without rebuilding the image.
What Interviewer Expects
- Knows ARG is build-time only and ENV is runtime
- Understands --build-arg vs docker run -e
- Knows ARG values are not in the running container
- Warns that secrets must not be passed as ARG
- Can show the ARG-into-ENV bridging pattern
Common Mistakes
- Expecting ARG values to be available at runtime
- Passing secrets via --build-arg (exposed in history)
- Referencing an ARG before it is declared in the stage
- Thinking ENV cannot be overridden at run time
- Forgetting ARG scope resets across build stages
Best Answer (HR Friendly)
“ARG is like setup information used only while building the image and then thrown away, while ENV is configuration stored inside the image that the running application can read. You often accept an ARG during the build and turn it into an ENV so it becomes a default the app uses later.”
Code Example
# Build-time only: not present in the running container
ARG NODE_VERSION=20
FROM node:${NODE_VERSION}-alpine
# Accept a build arg and promote it to a runtime env var
ARG APP_ENV=production
ENV APP_ENV=${APP_ENV}
WORKDIR /app
COPY . .
RUN npm ci --omit=dev
# APP_ENV is readable by the app at runtime
CMD ["node", "server.js"]
# Build: docker build --build-arg NODE_VERSION=22 --build-arg APP_ENV=staging -t app .
# Runtime override: docker run -e APP_ENV=development appFollow-up Questions
- Why should secrets never be passed via --build-arg?
- How does ARG scope behave across multi-stage builds?
- How do you override an ENV value at container run time?
- What is the predefined ARG list Docker provides (e.g. HTTP_PROXY)?
- How can BuildKit secrets safely provide build-time credentials?
MCQ Practice
1. Which variable type is available inside the running container?
ENV values persist in image metadata and are visible at runtime; ARG values exist only during the build.
2. How do you override an ARG when building an image?
ARG values are supplied at build time with docker build --build-arg NAME=value.
3. Why is passing a secret via --build-arg discouraged?
Build args can appear in the image history/metadata, so secrets should use BuildKit secret mounts instead.
Flash Cards
When is ARG available? — Only during the image build; it is not present in the running container.
When is ENV available? — In the running container at runtime, and it is baked into the image metadata.
How do you bridge ARG to runtime? — Set ENV KEY=$ARG so a build-time value becomes a runtime default.
How do you override ENV at run time? — docker run -e KEY=value