Build Contexts, .dockerignore, Remote Contexts, Named Contexts, and Deterministic Build Inputs: Concepts, Architecture, and Mental Model
A Docker build can only be reproducible when its input boundary is explicit. This lesson models local, Git, tar/URL, and named contexts; explains ignore filtering and BuildKit snapshots; and shows why a mutable branch or oversized context is an engineering input, not a harmless convenience.
Learning objectives
- Define the build context as the set of filesystem or remote-source inputs a builder may access, not merely the directory containing the Dockerfile.
- Trace local, Git, tar/URL, and named context sources through ignore filtering, BuildKit snapshots, COPY/ADD or RUN mounts, cache keys, and output images.
- Explain root .dockerignore behavior and Dockerfile-specific ignore-file precedence without assuming .gitignore semantics are identical.
- Distinguish a mutable branch or tag from a checksum-verified Git source and record the resolved source revision when reproducibility matters.
- Use builder progress, source hashes/revisions, image identity, and context configuration as auditable build-input evidence.
1. The problem: the Dockerfile is not the whole build input
Chapter 07 made the Dockerfile a source-controlled build contract.
That contract still cannot be interpreted without an input boundary.
When a Dockerfile says COPY . /app, the builder does
not read “the repository” in an abstract sense; it reads the build
context presented to it after ignore processing. If that context
contains credentials, build outputs, large dependency trees, or
unrelated source, those files can affect transfer time, cache keys,
and security even when the Dockerfile author did not intend them to
matter.
The first question for a reproducible build is therefore not only “which Dockerfile?” but also “which exact source set was the builder allowed to see, from where, at which revision, under which ignore rules?”
2. Mental model: source boundary → filtered snapshot → build dependency
flowchart TD
A[Local directory / Git / tar / URL / stdin] --> B[Context resolver]
B --> C[.dockerignore or Dockerfile-specific ignore]
C --> D[BuildKit context snapshot]
E[Named contexts] --> F[Independent snapshots]
D --> G[COPY / ADD / RUN mounts]
F --> G
G --> H[Cache keys + build result]
H --> I[Image ID / digest evidence]
The default context is selected by the positional argument of
docker build or docker buildx build. Named
contexts are additional inputs supplied explicitly with
--build-context. BuildKit resolves and snapshots those
inputs, then Dockerfile operations consume only the sources
referenced by the build graph.
3. Context types are different trust and transport models
| Context | Who supplies/fetches it | Identity evidence | Main risk |
|---|---|---|---|
| Local directory | Client-side source is prepared for the builder | Path + file hashes + ignore rules | Accidental broad context or local secret |
| Git repository | Builder resolves/clones remote source | URL + ref + resolved commit/checksum | Mutable branch/tag drift |
| Remote tar/URL | Builder fetches the remote input | URL + externally verified digest/version | Mutable or untrusted remote content |
| Named context | Supplied separately from default context | Name + source type + source identity | Name collision or unpinned secondary source |
| Empty/text context | Dockerfile text only | Dockerfile bytes | Assuming filesystem files are available when none are |
4. .dockerignore defines a build boundary, not a Git
boundary
Before a local filesystem context is sent to the builder, Docker
applies ignore rules from .dockerignore at the root of
that context. The syntax resembles .gitignore but
should not be treated as identical. Docker uses its own pattern
matching and preprocessing rules, including support for
** and negation with !. Review the Docker
rule set directly rather than copying repository ignore assumptions
blindly.
.git
.env
secrets/
node_modules/
dist/
*.log
!dist/release-manifest.json
Ignoring a path removes it from the build context. That reduces what
COPY/ADD can read and can reduce
transfer/cache invalidation. It is not a general secret-management
system: a secret needed during a build belongs in BuildKit
secret/SSH mounts, not in an unignored file.
5. Dockerfile-specific ignore files can intentionally narrow different builds
Docker supports ignore files named after a Dockerfile, such as
lint.Dockerfile.dockerignore or
docs.Dockerfile.dockerignore. When present next to that
Dockerfile, the Dockerfile-specific file takes precedence over the
root .dockerignore for that build. This is useful when
a repository has distinct build purposes, but it also creates a
precedence rule that must be reviewed during diagnosis.
6. A branch name is a selector; a commit/checksum is evidence
A Git context can select a branch, tag, ref, pull-request ref, or
subdirectory. Docker's current structured URL-query form is
recommended over older fragments when supported. For
release-critical inputs, pair the human-readable branch/tag/ref with
a checksum (alias commit) so the build
fails when the name resolves to an unexpected revision.
docker buildx build \
'https://github.com/example/project.git?tag=v1.2.3&subdir=docker&checksum=0123456789abcdef' \
--progress=plain
The checksum above is illustrative, not a real dependency. A real lab must obtain the expected revision from the reviewed upstream source and record it in the evidence packet.
7. Named contexts separate logical inputs
Named contexts let a build receive additional sources without
widening the default context. A build can expose
docs=./docs or a pinned image/Git source under a stable
logical name, and the Dockerfile can consume that context as if it
were a stage.
docker buildx build --build-context docs=./docs .
# syntax=docker/dockerfile:1
FROM busybox:1.37.0
WORKDIR /app
COPY . ./app
COPY --from=docs / ./docs
Named contexts improve boundary clarity only when each secondary source is itself identified and reviewed.
8. Builder location changes where remote inputs are fetched
With a remote tarball or remote builder, do not assume the machine running the Docker CLI performs every fetch or has the same filesystem paths as the builder. Treat client path, builder path, remote URL, and named-context source as different locations. This distinction becomes essential in CI and multi-node builder scenarios.
9. Build-input evidence map
Context type/root, ignore-file identity, intended included files, measured size, and BuildKit transfer/progress evidence.
URL, branch/tag/ref, checksum/commit, subdirectory, and actual resolved revision.
Logical name, source scheme/path, immutable source identity where possible, and how the Dockerfile consumes it.
Builder/frontend versions, image ID/digest, and the source-to-output assumptions recorded at build time.
10. Small challenge: draw the smallest safe context
A repository contains src/, docs/,
.git/, .env, a 500 MB
node_modules/, and a generated dist/. The
application image needs only src/ and one generated
manifest; documentation is processed separately. Decide what belongs
in the default context, what should be ignored, and whether
docs/ deserves a named context. State the evidence that
would prove your decision.
Knowledge check
Is the build context always the directory containing the Dockerfile?
No. The context is the positional source given to the build command and can be local, Git, tar/URL, stdin, or another supported source. The Dockerfile can also be selected separately.
Why can a Dockerfile-specific ignore file surprise an engineer
who only reads the root .dockerignore?
Because it takes precedence for that Dockerfile and can produce a different filtered context.
What does a Git branch name prove about immutable source identity?
Nothing immutable by itself. The branch is a mutable selector; record the resolved commit and use checksum verification where supported.
What problem do named contexts solve?
They expose additional logically separate build inputs without broadening the default context and let those inputs be identified independently.
Does ignoring a secret file make .dockerignore a
secret manager?
No. Ignore files reduce accidental context exposure. Required build secrets should use BuildKit secret or SSH mounts instead.
Official references and version notes
-
Build context
— authoritative behavior for local directories, Git repositories,
tarballs, stdin/empty contexts,
.dockerignore, Dockerfile-specific ignore files, Git URL queries/checksums, and named contexts. -
docker buildx build—--build-context, progress, outputs, metadata, and accepted named-context source types. -
Optimize cache usage
— why a small context improves transfer and cache behavior and how
.dockerignorereduces unnecessary input. -
Dockerfile reference
— how
COPY,ADD, andRUN --mountconsume build inputs. - Build best practices — source-control, cache, image, and reproducibility guidance.
- Docker Engine 29 release notes — current Engine baseline and fixes.
- Buildx releases — current Buildx feature/compatibility history.
- BuildKit releases — current BuildKit and built-in Dockerfile frontend releases.
Version-sensitive statements were rechecked against primary
documentation on 2026-09-21. Docker Engine 29.8.1
is the current Engine 29 patch release at this checkpoint; Buildx
0.37.1 and BuildKit 0.33.0 are current upstream baselines observed
in the current Docker packaging/release stream, and BuildKit
0.33.0 includes the built-in Dockerfile frontend 1.27.0. Docker
documents structured Git URL queries with
checksum/commit as requiring Buildx
0.28.0+, Dockerfile 1.18.0+, and Docker Desktop 4.46.0+ where
Desktop is used. Labs therefore record the learner's actual
builder/frontend state and include a local simulation path instead
of assuming remote Git-query support or network access.
Keep the academy open
Support free, practical DevOps education.
Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0
Send only Ethereum/ERC-20 compatible assets to this
address.