✦ For everyone, free.

Practical knowledge for real and everyday life

Home

19.1.1.3 Build Context Option

A focused guide to Build Context Option, connecting core concepts with practical Docker and container operations.

The build context option, specifically BuildKit's --build-context flag, allows specifying additional, independently named contexts beyond the single, primary build context every build already has, enabling a Dockerfile to reference files from an entirely separate directory, a remote Git repository, or even another image, without needing to restructure the project so everything lives within one single, traditional context boundary.

The primary context versus additional named contexts

Every build has exactly one primary, positional context argument, but --build-context adds further, independently named ones that a Dockerfile can reference explicitly through COPY --from=<name>:

docker buildx build --build-context shared=../shared-lib -t my-api .
COPY --from=shared utils.js ./lib/utils.js

This named context (shared, pointing at ../shared-lib) is referenced exactly the way a multi-stage build's earlier stage would be referenced, but it points at a genuinely separate directory rather than an earlier build stage, which is the specific capability this flag provides beyond what a traditional, single-context build supports.

Referencing a remote repository as a named context

A named context can point at a remote Git repository URL directly, rather than only a local directory, useful for pulling in a specific dependency or shared component maintained in its own separate repository without needing it checked out locally first:

docker buildx build \
  --build-context shared=https://github.com/example/shared-lib.git \
  -t my-api .
COPY --from=shared . /app/shared

This avoids needing a separate, manual checkout step before the build, since BuildKit itself fetches the referenced repository directly as part of resolving the named context.

Overriding a base image reference with a named context

A particularly useful application of this feature substitutes a named context in place of what a Dockerfile's FROM instruction would otherwise pull from a registry, which is valuable for testing a Dockerfile against a locally built or modified base image without needing to actually push that modified base image anywhere first:

FROM node:20 AS base
docker buildx build --build-context node:20=docker-image://my-custom-node:test -t my-api .

This substitutes a locally available, custom image in place of whatever the Dockerfile's own FROM node:20 would otherwise resolve to from the registry, which is genuinely useful for testing a base image change's downstream effects before committing to actually publishing that change anywhere.

Multiple named contexts in a single build

More than one --build-context flag can be supplied in the same build invocation, each independently referenceable by its own distinct name within the Dockerfile:

docker buildx build \
  --build-context shared=../shared-lib \
  --build-context config=../shared-config \
  -t my-api .
COPY --from=shared utils.js ./lib/
COPY --from=config app.config.json ./config/

This is a cleaner alternative to restructuring an entire monorepo's directory layout purely to bring multiple genuinely separate directories within a single, traditional build context boundary, allowing each one to remain organized independently while still being explicitly, deliberately accessible to a specific build that needs content from more than one of them.

Requiring BuildKit specifically

This capability is specific to BuildKit and the docker buildx build command; it is not available through the legacy builder or the plain docker build command in environments where BuildKit is not the active backend, which is worth confirming directly if this flag appears not to work as expected in a given environment.

docker buildx version

Confirming BuildKit is genuinely active and at a sufficiently current version rules out this specific, common cause before investigating any other possible explanation for the flag not behaving as documented.

Common mistakes

  • Attempting to use --build-context with the legacy builder or an environment where BuildKit is not actually the active backend, where the flag has no effect or is unrecognized entirely.
  • Restructuring an entire monorepo's directory layout to bring separate components within a single traditional context boundary, when named contexts would have achieved the same access without that restructuring effort.
  • Not considering a named context as a way to test a modified base image locally before committing to actually publishing that change to a registry.
  • Forgetting that a remote Git repository can itself serve as a named context, manually checking out a dependency locally first when the build itself could have fetched it directly.
  • Confusing a named context reference with a multi-stage build's earlier-stage reference, when the two are referenced through identical COPY --from= syntax but draw from entirely different sources.

The build context option's named multiple-context capability extends a Dockerfile's ability to draw from genuinely separate directories, remote repositories, or alternative base images, all addressable through the same familiar COPY --from= syntax already used for multi-stage builds, without requiring a project's actual directory structure to be reorganized purely to satisfy the constraint of a single, traditional build context boundary.