✦ For everyone, free.

Practical knowledge for real and everyday life

Home

19.1.1.4 Build Arg Option

A focused guide to Build Arg Option, connecting core concepts with practical Docker and container operations.

The build arg option, --build-arg, passes a value into the build process for use by a matching ARG instruction in the Dockerfile, and understanding its precedence relative to a Dockerfile's own default values, its shorthand for inheriting from the shell environment, and the set of automatically available platform-related arguments clarifies behavior that is easy to get subtly wrong.

Basic usage and Dockerfile correspondence

A --build-arg value only has any effect if the Dockerfile actually declares a matching ARG instruction to receive it; supplying a build arg with no corresponding declaration is silently ignored entirely:

docker build --build-arg NODE_ENV=production -t my-api .
ARG NODE_ENV
RUN echo "Building for $NODE_ENV"

Without the ARG NODE_ENV declaration present in the Dockerfile, the --build-arg flag's value would simply have no effect anywhere in the build, with no error or warning indicating the mismatch.

Precedence between CLI value and Dockerfile default

A Dockerfile's ARG instruction can specify a default value, and an explicit --build-arg value passed on the command line always overrides that default when both are present:

ARG NODE_ENV=development
docker build -t my-api .
docker build --build-arg NODE_ENV=production -t my-api .

The first build uses the Dockerfile's own default (development), since no override was supplied; the second explicitly overrides it to production, which is the expected, straightforward precedence behavior worth confirming directly whenever unsure which value is actually taking effect in a specific build invocation.

Supplying multiple build arguments

The flag can be repeated for each distinct argument needing a value:

docker build \
  --build-arg NODE_ENV=production \
  --build-arg BUILD_VERSION=1.4.2 \
  --build-arg ENABLE_TELEMETRY=false \
  -t my-api .

Each repetition is independent, with no limit on how many distinct build arguments a single build invocation can supply beyond whatever the Dockerfile itself actually declares and uses.

Inheriting a value from the shell environment

Supplying --build-arg with just a name and no explicit value pulls that value directly from the shell environment the build command itself is running in, which is convenient for passing through a value already set as an environment variable without needing to repeat it explicitly:

export NPM_TOKEN=abc123
docker build --build-arg NPM_TOKEN -t my-api .

This shorthand is functionally equivalent to explicitly writing --build-arg NPM_TOKEN=abc123, but avoids the redundancy of typing the value a second time when it already exists as a shell environment variable, and is particularly common in CI scripts where many values are already available as environment variables by the time the build command actually runs.

Predefined, automatically available build arguments

Docker automatically makes several specific arguments available without needing them explicitly passed via --build-arg at all, most notably the platform-related arguments useful for cross-compilation logic within a Dockerfile:

ARG TARGETPLATFORM
ARG TARGETOS
ARG TARGETARCH
ARG BUILDPLATFORM

RUN echo "Building on $BUILDPLATFORM for $TARGETPLATFORM"

These specific arguments are automatically populated by BuildKit based on the actual build and target platforms in effect, particularly relevant for a multi-platform build where a Dockerfile's own logic needs to branch based on which specific architecture it is currently building for.

RUN if [ "$TARGETARCH" = "arm64" ]; then \
      echo "ARM-specific step"; \
    fi

Build args are not the same as ENV

It is worth reiterating the distinction covered in dedicated baked-configuration content: ARG values exist only during the build and do not persist into the running container's environment unless a corresponding ENV instruction also captures the value, which means --build-arg is never the appropriate mechanism for supplying a value the running application itself needs to read at runtime.

ARG BUILD_VERSION
ENV APP_VERSION=$BUILD_VERSION

This explicit pattern, an ARG capturing the build-time value and a subsequent ENV instruction promoting it into the running container's environment, is the correct way to make a build-time-supplied value also available to the application at runtime, rather than assuming ARG alone accomplishes this.

Common mistakes

  • Passing a --build-arg value with no corresponding ARG declaration in the Dockerfile, having it silently ignored with no error or warning.
  • Assuming a --build-arg value automatically becomes available to the running container, without the explicit ARG-to-ENV promotion pattern needed for that.
  • Not using the name-only shorthand to inherit a value already present in the shell environment, redundantly repeating its value explicitly instead.
  • Overlooking the automatically available platform-related build arguments, manually attempting to detect target architecture through some other, less reliable mechanism instead.
  • Not verifying which value, an explicit override or a Dockerfile's own default, is actually taking effect in a specific build invocation when both are present.

The build arg option correctly supplies build-time-only values to a matching ARG declaration, with explicit CLI values always overriding Dockerfile defaults, a convenient shell-environment-inheritance shorthand, and a useful set of automatically populated platform arguments, all of which require the value to be explicitly promoted through ENV if the running application itself genuinely needs to read it afterward.