ARG Instruction Reference

Define build-time variables that users can pass at build-time

Syntax

ARG <name>[=<default value>]

The ARG instruction defines a variable that users can pass at build-time to the builder with the docker build command using the --build-arg <varname>=<value> flag.

The ARG instruction allows you to define variables that can be passed at build-time to customize your builds. Unlike ENV instructions, ARG values are not available to containers running from the final image.

ARG instructions are particularly useful for creating flexible Dockerfiles that can be customized without modification. They allow users to specify values like version numbers, repository URLs, or other build-specific configurations when they run docker build.

Description

The ARG instruction defines a variable that users can pass at build-time to the builder. This allows for dynamic configuration of the build process without changing the Dockerfile.

An ARG instruction can include a default value that will be used if no value is passed at build-time. For example:

ARG VERSION=latest

In this case, VERSION will default to "latest" if not specified by the user.

To pass a value at build-time, you would use the --build-arg flag:

docker build --build-arg VERSION=1.0 -t myimage .

ARG values can be referenced in subsequent Dockerfile instructions using the familiar shell syntax:

ARG VERSION=latest
FROM ubuntu:${VERSION}

Unlike ENV variables, ARG values do not persist in the built image. They are only available during the build process and not to containers created from the image. If you need a value to be available at runtime, you should use ENV instead, or combine ARG and ENV:

ARG VERSION=latest
ENV VERSION=${VERSION}

Scope and Precedence

ARG instructions have specific scoping rules in Dockerfiles:

Default Scope

An ARG instruction goes into effect from the line it is defined and lasts until the end of the build stage.

FROM ubuntu:20.04
# ARG VERSION is not available here
ARG VERSION=1.0
# ARG VERSION is available here and below
Pre-FROM ARG

ARG instructions defined before the first FROM are called "global" and can be used in any FROM instruction.

ARG BASE_IMAGE=ubuntu:20.04
FROM ${BASE_IMAGE}
# ARG BASE_IMAGE is still available here, but only for reference

These pre-FROM ARG values are not available for use inside instructions after the FROM line unless they are redefined with a new ARG instruction in that build stage.

Multi-stage ARG

In multi-stage builds, each FROM instruction starts a new build stage with its own scope.

ARG VERSION=1.0  # Global
FROM ubuntu:20.04 AS builder
ARG VERSION        # Redeclared in this stage
RUN echo ${VERSION}

FROM alpine:3.14 AS runner
ARG VERSION        # Must be redeclared in this stage too
RUN echo ${VERSION}
Predefined ARGs

Docker has a set of predefined ARG variables that you can use without declaring them:

  • HTTP_PROXY, http_proxy
  • HTTPS_PROXY, https_proxy
  • FTP_PROXY, ftp_proxy
  • NO_PROXY, no_proxy
  • TARGETPLATFORM, TARGETOS, TARGETARCH

These can be used directly in your Dockerfile:

FROM ubuntu:20.04
RUN echo "Building for architecture: ${TARGETARCH}"

Examples

Basic Usage

Defining a simple build argument with a default value:

FROM ubuntu:20.04
ARG VERSION=1.0
RUN echo "Building version: ${VERSION}"

The VERSION argument defaults to 1.0 but can be overridden at build time.

Dynamic Base Image

Using ARG to determine the base image:

ARG BASE_IMAGE=ubuntu:20.04
FROM ${BASE_IMAGE}
RUN echo "Using base image: ${BASE_IMAGE}"

This allows building from different base images without modifying the Dockerfile.

Package Installation

Using ARG to control which packages to install:

FROM ubuntu:20.04
ARG PACKAGES="vim curl git"
RUN apt-get update && apt-get install -y ${PACKAGES}

This makes it easy to customize which packages are installed during the build.

Setting Environment Variables

Combining ARG and ENV to set runtime configuration:

FROM node:18-alpine
ARG NODE_ENV=production
ENV NODE_ENV=${NODE_ENV}
RUN echo "Building with NODE_ENV=${NODE_ENV}"

This allows customizing the NODE_ENV value at build time, and persisting it for runtime.

Conditional Logic

Using ARG for conditional build steps:

FROM ubuntu:20.04
ARG ENVIRONMENT=production

RUN if [ "$ENVIRONMENT" = "development" ]; then \
      apt-get update && apt-get install -y vim git curl; \
    else \
      apt-get update && apt-get install -y curl; \
    fi

This example installs different packages based on the build environment.

Multi-stage Build with ARG

Using ARG in a multi-stage build:

ARG VERSION=latest

FROM node:18 AS builder
ARG VERSION
RUN echo "Building version: ${VERSION}"
# Build commands here...

FROM nginx:alpine AS runtime
ARG VERSION
LABEL version="${VERSION}"
# Copy from builder stage
COPY --from=builder /app/dist /usr/share/nginx/html

Note how the ARG needs to be redeclared in each stage to be available.

Best Practices

  • Provide default values: Always include sensible default values for ARG instructions to ensure the Dockerfile works without requiring build arguments.
  • Document ARG instructions: Add comments explaining what each ARG is for and what values are acceptable.
  • Use for build-time customization: Use ARG for values that should be customizable at build-time but don't need to be available at runtime.
  • Combine with ENV for runtime variables: If a value is needed at both build-time and runtime, define it with ARG and then set it as an ENV variable.
  • Be careful with secrets: ARG values are visible in the image history. Don't use ARG for sensitive information like passwords or API keys.
  • Group related ARG instructions: Place related ARG instructions together to make the Dockerfile more readable.
  • Consider multi-platform builds: Use ARG and BuildKit's predefined ARGs like TARGETARCH for multi-platform images.
  • Redeclare in each stage: Remember to redeclare ARG instructions in each build stage where they are needed.

ARG vs ENV

It's important to understand the difference between ARG and ENV instructions:

ARG ENV
Only available at build time Available at both build time and runtime
Does not persist in the final image Persists in the final image
Can be set at build time with --build-arg Can be overridden at container runtime with -e
Used for build-time customization Used for runtime configuration

If you need a value only during the build process, use ARG. If you need a value to be available to the running container, use ENV.

You can combine ARG and ENV to create build-time configurable runtime environments:

ARG NODE_ENV=production
ENV NODE_ENV=${NODE_ENV}

This allows you to set NODE_ENV at build time with --build-arg, while still making it available at runtime as an environment variable.

Notes and Limitations

  • ARG values are not persisted in the final image, unlike ENV values.
  • ARG values are visible in the image history, so don't use them for secrets.
  • ARG instructions defined before a FROM are only available for use within FROM lines unless they are redeclared after the FROM.
  • Each build stage in a multi-stage build has its own scope for ARG values. You need to redeclare ARG in each stage where you want to use it.
  • ARG values can be overridden by environment variables with the same name when using docker build, but only if the ARG is defined in the Dockerfile.
  • Docker has a set of predefined ARG variables (like HTTP_PROXY, TARGETARCH) that you can use without declaring them.
  • ARG values can be referenced in almost all Dockerfile instructions, but there are some limitations with ONBUILD instructions.
  • The ARG instruction does not create a layer in the image like ENV does.

Try Our Optimizer

Analyze your Dockerfile for optimization opportunities.

Dockerfile Optimizer