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.
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.
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:
- After creating and bootstrapping the builder, what new Docker/Buildx state will exist?
-
After a
--loadbuild, where should the result be observable? - After an OCI exporter build, where should the result be observable and where should it not be assumed to exist?
- 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
Docker context, Engine/CLI, Buildx, builder name/driver/node, BuildKit version, worker platforms.
# syntax, Dockerfile hash, payload hash, context
assumptions.
Plain logs, build records, step/cache evidence, timestamps.
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.
Knowledge check
What proves Build A reached the local Docker image store?
The successful local image inspection and runtime check, not merely the BuildKit DONE lines.
What proves Build B produced an OCI archive?
The archive file, checksum, and valid OCI layout contents.
Why might the second build contain many cache hits?
The source and build graph are unchanged, so BuildKit can reuse prior operation results even though the exporter differs.
If history ls is unavailable, should you fabricate
a build ID for the evidence packet?
No. Record the tool limitation and keep plain logs/version evidence.
What does Chapter 10 add to this evidence model?
It separates build stages and runtime stages so you can prove which files/tools/configuration are present in the final image.
Official references and version notes
- Builders — Buildx builder instances, nodes, drivers, and builder selection.
-
Build drivers
— current
docker,docker-container,cloud,kubernetes, andremotedriver behavior and capabilities. - Docker container driver — isolated BuildKit container lifecycle, driver options, and explicit output behavior.
- Docker Buildx CLI — builder override, subcommands, and current Buildx surface.
-
docker buildx build— progress modes, exporters, metadata,--load,--push, and output semantics. -
docker buildx inspect— builder/driver/nodes/status/platform and bootstrap evidence. - Build history — recorded build IDs, status, time, duration, logs, and record inspection.
- Exporters — image, registry, local, tar, OCI, and Docker build-result destinations.
- OCI and Docker exporters — OCI/Docker archive semantics and compatible drivers.
- Dockerfile reference — Dockerfile frontend syntax and build instruction semantics.
- Buildx releases — upstream Buildx release history.
- BuildKit releases — BuildKit and built-in Dockerfile frontend release history.
- Docker Engine 29 release notes — current Engine baseline and bundled component updates.
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.
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0
Send only Ethereum/ERC-20 compatible assets to this
address.