Build args pass values into a build, such as a version or a target platform, and are referenced with ARG. They are convenient but visible in image history, so they are the wrong place for secrets. Environment variables are for the running container, a different phase.
Before you start
You should be comfortable with Dockerfiles and the build process. This article covers ARG and its boundaries.
Step-by-step walkthrough
Step 1: Scope build args correctly
An ARG is available only in the stage where it is declared; a second stage must declare it again. Use args for values that shape the build, such as NODE_VERSION or a git commit, and set defaults so the build works without them.
Step 2: Never pass secrets as build args
Build args are recorded in image metadata and history, so a secret passed this way is recoverable from the image. Use a build secret (RUN --mount=type=secret) or fetch credentials only at runtime, so they never land in a layer.
Step 3: Watch cache interactions
Changing an ARG value used in a RUN invalidates that layer and everything after it, so a frequently changing arg like a commit hash busts the cache early. Order instructions so volatile args come after the expensive, stable layers.
Worked scenario
The arg shapes the build and is re-declared per stage.
ARG NODE_VERSION=22
FROM node:${NODE_VERSION}-alpine
ARG NODE_VERSION
RUN echo "building for node ${NODE_VERSION}"Walk through the example
The top-level ARG parameterizes the base image, and the second ARG re-declares it inside the stage so it is usable there. Changing NODE_VERSION rebuilds from the base image onward. Because the value is not a secret, recording it in history is fine; a token would not be.
Common mistake
Passing a token or password as --build-arg, which is stored in the image and visible to anyone who has it. Another is putting a volatile arg before heavy steps, so the cache is invalidated unnecessarily.
Verify the behavior
Build with an arg and inspect the image history to confirm the value is recorded. Change the arg and confirm the affected layer rebuilds. Confirm a secret is provided via a build secret or at runtime, not as an arg.
Interview exercise
Why are build args unsafe for secrets?
Answer and reasoning
Because their values are stored in the image configuration and appear in the build history, so anyone with the image can read them. A layer’s contents are effectively public to anyone who can pull the image. Secrets belong in build-time secret mounts or in runtime injection, not in build args.
Continue learning
Compare secret handling in Docker secrets in builds and env config in Entrypoint vs CMD. Read the Docker build variables documentation and try the Docker interview questions.