Build-Time Variables
Control builds dynamically with ARG and ENV.
ARG - Build-Time Variables
# Define build argument
ARG NODE_VERSION=20
FROM node:${NODE_VERSION}-alpine
# Use with default
ARG APP_VERSION=1.0.0
LABEL version="${APP_VERSION}"
# Required argument (no default)
ARG API_URL
RUN echo "API: ${API_URL}"# Override at build time
docker build --build-arg NODE_VERSION=18 -t myapp .
docker build --build-arg APP_VERSION=2.0.0 -t myapp .
docker build --build-arg API_URL=https://api.example.com -t myapp .ENV - Runtime Variables
# Set environment variables
ENV NODE_ENV=production
ENV PORT=3000
# Multiple variables
ENV NODE_ENV=production \
PORT=3000 \
LOG_LEVEL=info
# Available at runtime
CMD echo "Running on port ${PORT}"ARG vs ENV
| Aspect | ARG | ENV |
|---|---|---|
| Available | Build time only | Build + Runtime |
| Override | --build-arg | -e or --env |
| Persists | No (not in image) | Yes (in image) |
| Use case | Version, URLs | Config, settings |
Converting ARG to ENV
# ARG only available during build
ARG APP_VERSION=1.0.0
# Convert to ENV for runtime
ENV APP_VERSION=${APP_VERSION}
# Now available at runtime
CMD echo "Version: ${APP_VERSION}"Predefined ARGs
# Docker provides these automatically
ARG TARGETPLATFORM
ARG TARGETOS
ARG TARGETARCH
ARG BUILDPLATFORM
ARG BUILDOS
ARG BUILDARCH
# Use for multi-platform builds
FROM --platform=${BUILDPLATFORM} golang:1.22 AS builder
RUN GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -o appPractical Examples
Version-Based Builds
ARG NODE_VERSION=20
ARG ALPINE_VERSION=3.19
FROM node:${NODE_VERSION}-alpine${ALPINE_VERSION}
ARG APP_VERSION=dev
ENV APP_VERSION=${APP_VERSION}
LABEL version="${APP_VERSION}"# Build with specific versions
docker build \
--build-arg NODE_VERSION=18 \
--build-arg APP_VERSION=1.2.3 \
-t myapp:1.2.3 .Environment-Specific Builds
ARG ENVIRONMENT=production
FROM node:20-alpine
ARG ENVIRONMENT
ENV NODE_ENV=${ENVIRONMENT}
COPY package*.json ./
RUN if [ "${ENVIRONMENT}" = "development" ]; then \
npm install; \
else \
npm ci --only=production; \
fi
COPY . .
CMD ["node", "server.js"]Private Registry Authentication
ARG REGISTRY_URL=docker.io
ARG BASE_IMAGE=node:20-alpine
FROM ${REGISTRY_URL}/${BASE_IMAGE}
# ...Security Considerations
# Bad: Secrets visible in image history
ARG SECRET_KEY
RUN curl -H "Authorization: ${SECRET_KEY}" https://api.example.com
# Good: Use BuildKit secrets
RUN --mount=type=secret,id=api_key \
curl -H "Authorization: $(cat /run/secrets/api_key)" https://api.example.com# Pass secret at build time
docker build --secret id=api_key,src=./api_key.txt -t myapp .Best Practices
- Use defaults - Always provide sensible defaults for ARG
- Document ARGs - Comment what each ARG is for
- Don't expose secrets - ARG values visible in
docker history - Convert to ENV - When runtime access is needed
- Use in FROM - ARG before FROM for base image selection
- dockerfile
- arg
- env
- variables
- build-time