...

Comprehensive Guide to Docker Build Arguments

December 9, 2024 · 8 minutes read

Reviewed by: Julia Knights
Credit: Codesphere

Table of Contents

Docker has revolutionized software development by simplifying how we package, distribute, and deploy applications. One of its most powerful features is the ability to customize the build process using Docker build arguments. These build-time variables provide flexibility and allow developers to tailor their images for specific use cases. In this article, we’ll explore the intricacies of Docker build arguments, their use cases, and best practices for integrating them effectively into your workflows.


Understanding Docker Build Arguments

Docker build arguments, or build args, are variables available only during the image build phase. Defined in a Dockerfile using the ARG instruction, they enable developers to create configurable and reusable build scripts. These arguments are passed at build time via the --build-arg flag in the docker build command.

Unlike environment variables (ENV), build args:

  • Exist solely during the build process.
  • Do not persist in the resulting image.
  • Are not accessible within containers running from the image.

Here’s a simple example:

# Dockerfile
ARG IMAGE_VERSION=3
FROM alpine:${IMAGE_VERSION}

This example allows you to dynamically change the base image version during the build process:

docker build --build-arg IMAGE_VERSION=latest -t my-image:latest .

By passing IMAGE_VERSION=latest, the image is built from alpine:latest instead of the default alpine:3.


Benefits of Using Docker Build Arguments

Build args provide several advantages that enhance Docker’s flexibility:

  1. Customizable Builds:
    • Dynamically adjust configurations, such as selecting specific versions of a base image.
    • Create multiple variations of the same image by tweaking build parameters.
  2. Improved Maintainability:
    • Reduce redundancy by consolidating variations into a single Dockerfile.
    • Enable dynamic features without modifying the Dockerfile itself.
  3. Scripting Convenience:
    • Integrate with environment variables to avoid hardcoding values in scripts.
    • Simplify CI/CD pipelines by passing build-specific variables.

Defining and Using Build Args in Dockerfiles

1. Declaring Build Args: To declare a build arg in a Dockerfile, use the ARG instruction. Optionally, you can provide a default value:

ARG VAR_NAME=default_value

Multiple build args can be defined:

ARG FOO
ARG BAR=42

2. Referencing Build Args: Build args can be used in supported instructions like FROM, RUN, LABEL, and ENV:

ARG APP_VERSION
LABEL version=${APP_VERSION}

3. Passing Build Args: Pass values for build args using the --build-arg flag:

docker build --build-arg FOO=example --build-arg BAR=100 -t my-image .

If a value isn’t specified, the default value from the Dockerfile is used.


Advanced Features and Best Practices

Using Build Args from Shell Variables

To streamline builds, you can pass shell environment variables directly as build args:

export APP_ENV=production
docker build --build-arg APP_ENV -t my-image .

This propagates the value of APP_ENV from the shell to the build process.

Making Build Args Mandatory

By default, Docker treats build args as optional. However, you can enforce required input using shell validation within the Dockerfile:

ARG REQUIRED_ARG
RUN test -n "${REQUIRED_ARG}" || exit 1

If REQUIRED_ARG is not provided, the build fails with an error.


Predefined Build Arguments

Docker provides several built-in build args that require no explicit ARG declaration. These include:

  • Proxy settings (HTTP_PROXY, HTTPS_PROXY, etc.).
  • Build environment details:
    • BUILDPLATFORM, BUILDOS, BUILDARCH, and BUILDVARIANT for the current build context.
    • TARGETPLATFORM, TARGETOS, TARGETARCH, and TARGETVARIANT for the target platform.

Example usage:

ARG TARGETARCH
RUN curl -O https://example.com/binary-${TARGETARCH}.tar.gz

Common Use Cases for Build Args

  1. Versioning and Tagging:
    • Dynamically set base image tags.
    • Define application versions or build metadata.
  2. Feature Toggles:
    • Enable or disable optional components or features at build time.
    • Use build args to populate container environment variables:
    • Default Environment Variables:
  3. Default Environment Variables:
  4. Platform-Specific Builds:
    • Use predefined build args like TARGETARCH to create architecture-specific images.

Limitations of Docker Build Arguments

While build args are a powerful tool, they have some limitations:

  1. Scope

Build args are available only after their declaration and are discarded at the end of each build stage. In multi-stage builds, you must redefine build args in every stage where they’re needed:

ARG BUILD_VERSION
FROM alpine AS base
RUN echo ${BUILD_VERSION}

FROM scratch
ARG BUILD_VERSION
RUN echo ${BUILD_VERSION}

     2. Limited Instructions:

    • Build args work only with instructions like FROM, RUN, and LABEL. Unsupported instructions will ignore them.

     3. Not Suitable for Secrets:

      • Build args are stored in image metadata and can be retrieved using docker history. For secrets, use Docker’s build secrets.

Build Args vs. Environment Variables (ARG vs. ENV)

Build args and environment variables serve different purposes:

Aspect Build Args Environment Variables
Scope Build phase only Runtime inside containers
Persistence Not saved in the image Saved in the image and accessible
Usage Configure build behavior Configure container behavior

To combine both, assign build arg values to environment variables:

ARG FEATURE_ENABLED=0
ENV FEATURE_ENABLED=${FEATURE_ENABLED}

Real-World Example: Multi-Stage Build with Build Args

Here’s a practical example of using build args in a multi-stage Dockerfile:

ARG NODE_VERSION=16
FROM node:${NODE_VERSION} AS builder
WORKDIR /app
COPY . .
RUN npm install && npm run build
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html

In this setup:

  • The NODE_VERSION build arg specifies the Node.js version.
  • The build stage compiles the app using the specified Node.js version.
  • The production stage uses Nginx to serve the compiled files.

Conclusion

Docker build arguments are a powerful tool for creating customizable and reusable Dockerfiles. They simplify dynamic configurations, enable versioning, and improve maintainability. By combining build args with environment variables, developers can ensure flexible and robust builds tailored to diverse needs.

Want to master more Docker techniques? Follow CereBrix for expert insights and practical guides. Stay connected with us on social media at @cerebrixorg!

Franck Kengne

Tech Visionary and Industry Storyteller

Seraphinite AcceleratorOptimized by Seraphinite Accelerator
Turns on site high speed to be attractive for people and search engines.