Chapter 08Lesson 01~95 minutes

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.

Build contextBuildKitdockerignoreGit contextNamed contexts

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.
Chapter 08 evidence baseline — verified 2026-09-21. Mandatory exercises use synthetic local source, fake credential-shaped data, disposable chapter-owned images, and no production repositories or credentials. Docker Engine 29.8.1 is the current Engine 29 patch baseline at verification time; current packaging/release evidence also places Buildx 0.37.1 and BuildKit 0.33.0 in the present toolchain stream. Current Docker documentation defines build context as the files/source a builder may access, documents Dockerfile-specific ignore precedence, recommends structured Git URL queries, and supports checksum/commit verification plus named contexts. Because these capabilities are version-sensitive, every executable lab captures the actual Engine/CLI/Buildx/builder/frontend state and provides a local simulation path when network or compatible remote-Git-query support is unavailable.

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

Build-input ownership
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

Default context

Context type/root, ignore-file identity, intended included files, measured size, and BuildKit transfer/progress evidence.

Remote source

URL, branch/tag/ref, checksum/commit, subdirectory, and actual resolved revision.

Named context

Logical name, source scheme/path, immutable source identity where possible, and how the Dockerfile consumes it.

Output

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.

Next lesson

Next: Guided Hands-On Workflow and Core Operations

Measure a real disposable context, shrink it, and prove what BuildKit receives.

Knowledge check

Is the build context always the directory containing the Dockerfile?

Why can a Dockerfile-specific ignore file surprise an engineer who only reads the root .dockerignore?

What does a Git branch name prove about immutable source identity?

What problem do named contexts solve?

Does ignoring a secret file make .dockerignore a secret manager?

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 .dockerignore reduces unnecessary input.
  • Dockerfile reference — how COPY, ADD, and RUN --mount consume 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 and compatibility note

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.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0 Send only Ethereum/ERC-20 compatible assets to this address.