Chapter 08Lesson 04~110 minutes

Build Contexts, .dockerignore, Remote Contexts, Named Contexts, and Deterministic Build Inputs: Diagnostics, Failure Modes, Security, and Performance

Context failures often look like missing files, stale caches, surprising network activity, or slow builds. This lesson preserves build evidence and diagnoses leaked files, incorrect ignore assumptions, mutable Git refs, remote-builder path confusion, and accidental context expansion without destructive cleanup.

DiagnosticsContext leaksIgnore rulesRemote buildersFailure evidence

Learning objectives

  • Preserve Dockerfile text, ignore rules, build command, builder identity, plain progress, source revision, and image identity before changing anything.
  • Diagnose accidental .git/credential/build-output transfer, incorrect .dockerignore patterns, and Dockerfile-specific ignore precedence.
  • Recognize mutable Git-ref drift and use checksum verification rather than trusting a branch or tag name alone.
  • Distinguish client-side context preparation from builder-side remote fetching and filesystem access.
  • Apply the smallest source-controlled correction and verify context size/input identity again.
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. Diagnostic method: preserve the input contract first

Before editing ignore rules or changing the build command, capture the failing Dockerfile, context argument, ignore files, builder identity, plain progress, source revision, and output/error. Context failures are often made harder by “trying a different directory” until the build works, which erases the original dependency mistake.

docker context show
docker version
docker buildx version
docker buildx inspect
git rev-parse HEAD 2>/dev/null || true
cat .dockerignore 2>/dev/null || true
docker buildx build --progress=plain --no-cache . 2>&1 | tee first-failure.log

--no-cache is shown only as a bounded diagnostic comparison for a disposable lab; it is not a first-line production fix.

2. Failure: credentials, .git data, outputs, or dependencies enter the context

Symptoms include unexpectedly large context transfer, slow remote builds, surprising cache invalidation, or secret scanners reporting files that were never meant to be part of the image. Diagnose the context boundary first: list source files, inspect root/Dockerfile-specific ignore rules, and compare the plain progress transfer line.

Do not prove this with a real secret. Use a fake credential-shaped file. If a real credential may have entered a build context, treat it as potentially exposed according to your organization's incident process even if the Dockerfile did not copy it.

3. Failure: assuming .dockerignore equals .gitignore

A pattern copied from Git may match differently than expected. Docker preprocesses patterns, uses Go filepath-style matching, supports **, and honors negation order. Reduce the case to a tiny disposable tree and test one rule at a time. Keep the explanation in the evidence packet so future maintainers know why the pattern exists.

dist/**
!dist/release-manifest.json

The order matters: later negation can re-include an otherwise excluded path when its parent matching permits it. Test rather than assume.

4. Failure: the wrong ignore file is being read

A build using -f lint.Dockerfile may be governed by lint.Dockerfile.dockerignore, not the root file. When a file is unexpectedly missing—or unexpectedly present—record the selected Dockerfile and inspect the associated ignore file before changing COPY.

5. Failure: remote branch or tag moved

A build that succeeded yesterday can produce different source today if it uses only a mutable branch or tag. Preserve the current resolved commit and compare it to the reviewed release revision. With compatible tooling, add a checksum/commit query so the build fails when the selector points somewhere unexpected instead of silently accepting drift.

Expected selector: tag=v1.2.3
Expected commit: 0123456789abcdef...
Observed commit: fedcba9876543210...
Result: stop; investigate upstream ref movement before rebuilding

6. Failure: client path confused with builder path

Suppose the Dockerfile tries COPY ../shared/config.json /app/. Docker prevents escaping the context root, and a remote builder would not have a contractual right to the client's parent path anyway. The fix is not --privileged, a broad host bind, or copying the entire workstation. Move the intended source under a reviewed context or expose it as a named context.

7. Intentionally broken lab: excluded file requested by COPY

mkdir -p broken-demo/secret-like
printf 'not-a-secret\n' > broken-demo/secret-like/token.txt
cat > broken-demo/Dockerfile <<'EOF'
# syntax=docker/dockerfile:1
FROM busybox:1.37.0
COPY secret-like/token.txt /demo/token.txt
EOF
printf 'secret-like\n' > broken-demo/.dockerignore

docker buildx build --progress=plain --load -t devops-academy-ch08:broken broken-demo \
  2>&1 | tee broken-demo/first-failure.log || true

The expected failure is a source-file/context error: the Dockerfile asks for a path that the ignore boundary deliberately removed. Preserve the error, then fix the design. For this synthetic case, the correct change is to decide whether the file is truly needed; because it is credential-shaped, the safer answer is not to re-include it. Replace it with a non-secret declared file or a BuildKit secret mount in a later secrets-focused lesson.

8. Performance diagnosis: measure, do not guess

Measure directory size, context-load bytes/time in plain progress, and cache reuse before changing patterns. A slow build can come from context transfer, remote source fetch, build execution, image export, registry transfer, or runtime startup. Label the layer correctly.

9. Evidence-first sequence

  1. Preserve the first failure and exact build command.
  2. Confirm context/builders and actual versions.
  3. Identify default and named context sources.
  4. Inspect root and Dockerfile-specific ignore files.
  5. Record Git/remote source identity and checksum expectations.
  6. Inspect plain BuildKit source/context steps.
  7. Correct only the causal input boundary.
  8. Rebuild the smallest disposable scope and compare evidence.
Next lesson

Next: Checkpoint Lab

Produce a complete, reviewable dossier connecting context design to image output.

Knowledge check

A remote build cannot find ../shared/config.json. Should you mount the client's filesystem root?

A tag-based Git build changed output without Dockerfile changes. Which evidence comes first?

Why preserve a failed COPY error before changing .dockerignore?

What should you measure before claiming context optimization improved performance?

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.