Chapter 09Lesson 05~130 minutes

Checkpoint Lab — BuildKit and buildx Architecture, Builders, Frontends, Progress, Outputs, and Modern Build Workflows

The checkpoint builds one source tree through a dedicated BuildKit builder, exports the result both to the local image store and to an OCI archive, records builder/worker/frontend/build/digest evidence, and proves why successful execution, cache retention, local load, filesystem export, and registry push are different output states.

Checkpoint labBuilder evidenceLocal loadOCI archiveCleanup

Learning objectives

  • Build one small application through a dedicated docker-container builder and record exact builder/worker/frontend evidence.
  • Export one result to the local Docker image store and another to an OCI archive, then verify each output independently.
  • Capture build records, plain logs, image/archive digests, source hashes, cache behavior, and assumptions/limitations.
  • Predict output state before each build and explain why a completed build does not imply a loaded or pushed image.
  • Perform exact chapter-owned cleanup and bridge the evidence model to Chapter 10 multi-stage/minimal-runtime builds.
Chapter 09 evidence baseline — verified 2026-09-21. Mandatory exercises use a synthetic local source tree and a uniquely named disposable docker-container builder; they do not require a registry, paid cloud builder, Kubernetes cluster, production daemon, or privileged shared CI runner. At verification time Docker Buildx 0.37.1 and BuildKit 0.33.0 are the current upstream releases; BuildKit 0.33.0 includes the built-in Dockerfile frontend 1.27.0, while Docker Engine 29.8.1 remains the current Engine 29 course baseline. Docker documents the docker driver as Engine-integrated with automatic local image loading, while docker-container/remote/Kubernetes-style drivers keep an unspecified-output result in BuildKit cache unless an exporter such as --load, --push, or --output is selected. Every lab therefore records the actual local Buildx/BuildKit/frontend/worker state and verifies output destination independently.

1. Checkpoint mission

Produce an auditable BuildKit execution dossier for one tiny image. You will create an isolated builder, capture versions and worker identity, build once with a local-image output and once with an OCI archive output, preserve build records/progress, compare cache behavior, and clean only the resources created by this checkpoint.

2. Predict state before execution

Write your answers into evidence/00-predictions.txt before running the build:

  1. After creating and bootstrapping the builder, what new Docker/Buildx state will exist?
  2. After a --load build, where should the result be observable?
  3. After an OCI exporter build, where should the result be observable and where should it not be assumed to exist?
  4. Which second build steps do you expect to be cached, and why?

3. Create the disposable project and evidence directory

mkdir -p ch09-checkpoint/evidence
cd ch09-checkpoint

BUILDER="devops-academy-ch09-checkpoint"
IMAGE="devops-academy-ch09-checkpoint:loaded"
OCI="ch09-checkpoint.oci.tar"

cat > Dockerfile <<'EOF'
# syntax=docker/dockerfile:1
FROM busybox:1.37.0
WORKDIR /app
COPY payload.txt ./payload.txt
RUN sha256sum /app/payload.txt > /app/payload.sha256
CMD ["sh", "-c", "cat /app/payload.txt && cat /app/payload.sha256"]
EOF

printf 'chapter-09-buildkit-checkpoint\n' > payload.txt
sha256sum Dockerfile payload.txt | tee evidence/01-source-sha256.txt

4. Capture host, client, context, and builder baseline

date -u +%Y-%m-%dT%H:%M:%SZ | tee evidence/02-started-at.txt
docker context show | tee evidence/03-context.txt
docker version | tee evidence/04-docker-version.txt
docker info | tee evidence/05-docker-info.txt
docker buildx version | tee evidence/06-buildx-version.txt
docker buildx ls | tee evidence/07-builders-before.txt

If this host is not disposable/authorized for local builder creation, stop the executable portion and complete the checkpoint as an evidence-design exercise. Do not repurpose a production builder.

5. Create and identify the BuildKit worker

docker buildx create --name "$BUILDER" --driver docker-container

docker buildx inspect --bootstrap "$BUILDER" \
  | tee evidence/08-builder-inspect.txt

docker buildx ls | tee evidence/09-builders-with-checkpoint.txt

From the inspection output, record the driver, node, endpoint, status, BuildKit version, and platforms in evidence/10-builder-summary.txt. Do not infer them from course examples.

6. Build A: explicit local-image output

docker buildx build \
  --builder "$BUILDER" \
  --progress=plain \
  --load \
  --label devops-academy.lab=ch09-checkpoint \
  -t "$IMAGE" \
  . 2>&1 | tee evidence/11-build-load.txt

docker image inspect "$IMAGE" \
  > evidence/12-image-inspect.json

docker image inspect "$IMAGE" --format '{{.Id}}' \
  | tee evidence/13-local-image-id.txt

docker run --rm "$IMAGE" | tee evidence/14-runtime-proof.txt

This proves the Docker exporter/import path succeeded and the application payload runs. It does not prove anything was pushed to a registry.

7. Build B: OCI archive output

docker buildx build \
  --builder "$BUILDER" \
  --progress=plain \
  --output type=oci,dest="$OCI" \
  . 2>&1 | tee evidence/15-build-oci.txt

sha256sum "$OCI" | tee evidence/16-oci-tar-sha256.txt
tar -tf "$OCI" | tee evidence/17-oci-files.txt

Compare 11-build-load.txt and 15-build-oci.txt. The second build should often reuse graph work because the source and graph are the same, while the exporter path differs. Preserve what your environment actually reports.

8. Inspect OCI metadata without conflating digests

mkdir -p oci-unpack
tar -xf "$OCI" -C oci-unpack
cat oci-unpack/index.json | tee evidence/18-oci-index.json
sha256sum oci-unpack/index.json | tee evidence/19-index-file-sha256.txt

The SHA-256 of index.json as a file is not automatically the same thing as a descriptor digest referenced by OCI metadata. Record values with labels that explain what bytes each digest addresses.

9. Capture build records and the most recent logs

docker buildx --builder "$BUILDER" history ls --no-trunc \
  | tee evidence/20-history.txt

docker buildx --builder "$BUILDER" history logs \
  | tee evidence/21-history-logs.txt

If these commands are unavailable in the installed Buildx version, record history feature not available with the Buildx version and keep the plain logs as the authoritative execution record.

10. Evidence packet review

Builder identity

Docker context, Engine/CLI, Buildx, builder name/driver/node, BuildKit version, worker platforms.

Frontend/source

# syntax, Dockerfile hash, payload hash, context assumptions.

Execution/cache

Plain logs, build records, step/cache evidence, timestamps.

Outputs

Local image ID/inspect/runtime evidence plus OCI archive checksum and metadata.

Add a short evidence/22-assumptions.txt explaining whether Docker Desktop/native Engine was used, whether the builder was single-platform, and which current versions differed from the course baseline.

11. Verify the predictions

Create evidence/23-prediction-results.txt and mark each earlier prediction as confirmed, disproved, or not observed. A disproved prediction is useful evidence when you explain which layer behaved differently and why.

12. Exact cleanup and rollback

docker image rm "$IMAGE" | tee evidence/24-image-cleanup.txt
rm -rf oci-unpack
rm -f "$OCI"

docker buildx rm "$BUILDER" | tee evidence/25-builder-cleanup.txt
docker buildx ls | tee evidence/26-builders-final.txt

date -u +%Y-%m-%dT%H:%M:%SZ | tee evidence/27-finished-at.txt

Do not use broad whole-system or whole-builder prune operations. Exact object names provide enough cleanup scope for this checkpoint.

13. Operational review and Chapter 10 handoff

Chapter 09 adds the build execution boundary to the evidence chain established in Chapters 07–08. You can now distinguish Dockerfile/frontend, Buildx client, builder/driver, BuildKit worker/cache, build record, and exporter/output state. That distinction prevents a common operational mistake: treating “BuildKit completed” as proof that an image is locally available, published, or deployable.

Chapter 10 applies this execution model to Multi-Stage Builds, Minimal Runtime Images, Distroless Patterns, Debug Stages, and Build Separation. The same builder/exporter evidence will let you prove which build-stage artifacts reach the final runtime image and which tools/dependencies remain behind.

Next chapter

Next: Multi-Stage Builds, Minimal Runtime Images, Distroless Patterns, Debug Stages, and Build Separation

Use BuildKit's graph execution model to separate build-time toolchains from minimal runtime deliverables.

Knowledge check

What proves Build A reached the local Docker image store?

What proves Build B produced an OCI archive?

Why might the second build contain many cache hits?

If history ls is unavailable, should you fabricate a build ID for the evidence packet?

What does Chapter 10 add to this evidence model?

Official references and version notes

Version and compatibility note

Version-sensitive statements were rechecked against primary sources on 2026-09-21. Buildx 0.37.1 is the current upstream Buildx release (2026-09-11), BuildKit 0.33.0 is the current upstream BuildKit release (2026-09-02), and that BuildKit release updates the built-in Dockerfile frontend to 1.27.0. Docker Engine 29.8.1 remains the current Engine 29 patch baseline used by this course at verification time. Tooling is independently versioned, so every lab captures the learner's actual Engine/CLI/Buildx/BuildKit/frontend/worker state instead of assuming these versions.

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.