How to define build-args in docker-compose?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
In Compose, build arguments are defined under build.args and passed to ARG instructions in the Dockerfile. They are useful for build-time choices such as selecting a base image tag, a tool version, or a build mode.
The important distinction is build-time versus runtime. args affect image creation. environment affects the running container.
Define ARG in the Dockerfile First
Compose can only pass values to arguments that your Dockerfile knows about. For example:
The important lines are the ARG instructions. Without them, Compose has nowhere to send the build arguments.
Pass Build Args in Compose
Now define them in compose.yaml or docker-compose.yml:
Then build:
That passes the two values into the Docker build for the web service.
Mapping Form and List Form
Compose accepts args in two common forms. The mapping form is the clearest:
You may also see list form:
Both work. The mapping form is usually easier to read and maintain.
Pass Values From the Shell or .env
Compose variable interpolation lets you pull values from your environment:
If APP_ENV is exported in the shell or defined in a .env file, Compose substitutes it. The :-dev part provides a default when the variable is missing.
This is useful for CI pipelines where the build version comes from the job environment.
Multi-Stage Builds Still Use the Same Mechanism
Build args are especially common in multi-stage Dockerfiles:
Then in Compose:
That lets you vary the builder image without editing the Dockerfile.
Build Args Are Not Secrets
This is the biggest misconception. Build args do not behave like a secure secret store. They may appear in build metadata, logs, or image history depending on how they are used.
So avoid using them for real secrets such as:
- API tokens
- private keys
- database passwords
For secrets, use dedicated secret mechanisms or inject values at runtime through a safer path.
ARG Versus ENV
A good rule:
- use
ARGfor values needed only while building - use
ENVfor values the container should have when it runs
Example runtime environment:
That is separate from build.args. Mixing them up is a very common source of confusion.
Common Pitfalls
The most common mistake is defining args in Compose but forgetting the matching ARG instructions in the Dockerfile.
Another is expecting a build arg to exist when the container starts. It will not, unless you explicitly copy it into an ENV or a file during the build.
Teams also pass secrets through build args because it feels convenient. That is usually a security mistake.
Finally, do not assume changing a build arg is free. It can invalidate Docker's build cache for later layers, which may be exactly what you want or exactly what you were trying to avoid.
Summary
- Define build-time variables with
ARGin the Dockerfile. - Pass values from Compose with
build.args. - Use environment interpolation for CI and per-environment builds.
- Treat build args as build-time inputs, not runtime environment variables.
- Do not use build args for real secrets.

