Docker Build-Args in Compose
What This Article Covers
- The difference between
argsandenvironment. - Passing build arguments to Dockerfiles.
- Using them in multi-stage builds.
- Tips for handling sensitive values.
- Common pitfalls to avoid.
Introduction: Docker Build-Args in Compose
When you build custom images with Docker Compose, you often need to pass information to the Dockerfile during the build process. This might include version numbers, architectures, repository URLs, or feature flags. Docker Compose handles this with build.args. Runtime environment variables, by contrast, are set with environment. Mixing these up can cause builds to fail or leak sensitive data into your image.
This article walks through how to use build-args correctly in Compose.
Key Concepts
- Build-Arg: A variable available during image construction.
- ENV: A variable inside the running container.
- ARG: The Dockerfile instruction for build arguments.
- .env: File containing Compose variables.
- Multi-Stage: A build with multiple stages.
- Cache: Build layer caching.
- Secret: A sensitive value kept out of the image.
args vs. environment
services:
app:
build:
context: .
args:
APP_VERSION: "1.2.3"
environment:
NODE_ENV: production
APP_VERSION is available during the build. NODE_ENV only exists at runtime.
Dockerfile with ARG
ARG APP_VERSION=1.0.0
FROM node:20
ENV APP_VERSION=${APP_VERSION}
RUN echo "Baue Version ${APP_VERSION}"
WORKDIR /app
COPY . .
RUN npm install
CMD ["node", "index.js"]
Using a .env File
.env:
APP_VERSION=1.2.3
BUILD_TARGET=production
services:
app:
build:
context: .
args:
APP_VERSION: ${APP_VERSION}
BUILD_TARGET: ${BUILD_TARGET}
In the Compose File
services:
app:
build:
context: .
dockerfile: Dockerfile
args:
- APP_VERSION
- BUILD_TARGET=production
When you specify only the name, Compose pulls the value from the environment.
Build-Args and Caching
Build-args form part of the cache key. When an ARG changes, the corresponding layer is rebuilt:
ARG APP_VERSION
FROM base
Set APP_VERSION as late as possible to preserve earlier layer caches.
Multi-Stage Builds with ARG
ARG BUILD_TARGET=production
FROM node:20 AS builder
WORKDIR /app
COPY package*.json .
RUN npm install
COPY . .
RUN npm run build
FROM node:20-alpine
COPY --from=builder /app/dist /app
CMD ["node", "/app/index.js"]
services:
app:
build:
context: .
args:
BUILD_TARGET: production
Sensitive Data
Build-args don’t appear in the running container, but they can be visible in image layers:
docker history mein-image
For secrets, use docker buildx build --secret or BuildKit secrets in Compose:
services:
app:
build:
context: .
secrets:
- npm_token
secrets:
npm_token:
file: ./npm_token.txt
Best Practices
- Use ARG for build-time only, ENV for runtime.
- Never pass sensitive values as build-args.
- Set ARGs late in the Dockerfile to preserve cache efficiency.
- Centralize values in
.env. - Define sensible defaults in the Dockerfile.
- Document which args each image requires.
Common Pitfalls
- ARG not found in container: Only ENV and explicit copies make values visible.
- Values in the image: ARGs can show up in image history.
- Wrong ordering: Changing an ARG invalidates the cache.
- .env not loading: File is in the wrong directory.
- Missing composition: Only use
argsin the Compose build block. - Secrets in build-args: A security risk.
Further Reading and Resources
- BotServ.de Docker Compose
- BotServ.de Docker Multi-Stage Builds
- BotServ.de Docker Image Optimization
- BotServ.de Docker Secrets
FAQ: Docker Build-Args in Compose
What’s the difference between args and environment?
args apply during the build, environment at runtime.
Are build-args visible inside the container? Not directly, unless you explicitly copy them into an ENV variable.
Can I load build-args from .env?
Yes, using ${VARIABLE} syntax in docker-compose.yml.
Should I pass secrets as build-args? No, use BuildKit secrets instead.
What happens if an ARG is missing? If the Dockerfile defines a default value, that’s used.
Sources and Further Reading
- Dockerfile ARG: https://docs.docker.com/engine/reference/builder/#arg
- Compose Build: https://docs.docker.com/compose/compose-file/build/
- BuildKit Secrets: https://docs.docker.com/build/building/secrets/
Summary: Docker Build-Args in Compose
Build-args let you pass information to the Dockerfile without leaving it in the running container. In Docker Compose, you set them via build.args and receive them in the Dockerfile with ARG. Environment variables, by contrast, are for runtime. For cache efficiency and security, place build-args late in the build, treat sensitive values as BuildKit secrets, and define defaults in your Dockerfile. By cleanly separating args from environment, you avoid most common build and security mistakes.


