Ch. 13 · Docker

Docker Build Args vs Environment and Secrets

Use build args for build-time configuration, keep secrets out of them, and understand how they interact with the cache.

~2 min readintermediateupdated Oct 5, 2026

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}"
dockerfile

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.

More in Docker

read ✓Docker · hard

Docker Distroless and Minimal Images

Ship images without a shell or package manager, copy only the runtime, and accept the debugging trade-off.

~2 min readread →
read ✓Docker · hard

Docker Image Vulnerability Scanning

Scan images for known CVEs in CI, set a policy that blocks the build, and rebuild when base images are patched.

~2 min readread →
read ✓Docker · mid

Docker Registry Authentication

Authenticate to private registries with credential helpers, pull secrets in Kubernetes, and scoped tokens.

~2 min readread →
esc