Checkpoint Lab — Images, Layers, Content-Addressable Storage, Manifests, Config Objects, and Image Identity
This checkpoint produces a compact image-identity dossier for one real multi-platform image. You will capture the published index, the locally selected platform image, config/Image ID, layer identities, RepoDigest, container evidence, and a reproducible pull/run by digest, then perform guarded cleanup.
Learning objectives
- Create an image-identity dossier that separates human reference, index/manifest identity, platform selection, config/Image ID, layers/DiffIDs, and local RepoDigest.
- Predict which local references and container objects will change before pulling, tagging, running, removing, and repulling by digest.
- Prove a reproducible pull/run using the digest captured from the registry rather than copying a hard-coded example digest.
- Record assumptions about Engine, Buildx, image store, architecture, and registry behavior so another engineer can interpret the evidence.
- Perform exact cleanup that removes only checkpoint-created objects while preserving unrelated shared content.
1. Checkpoint scenario and deliverable
You are handing an image to another engineer who must be able to
answer “what exactly is this image?” without trusting a tag alone.
Produce a directory named ch04-evidence containing
environment, registry, local-image, runtime, and cleanup evidence
for busybox:1.37.0.
The deliverable is an identity dossier, not a vulnerability or provenance assessment. Later chapters add those signals. This checkpoint proves content identity, platform selection, local materialization, and reproducible retrieval by the captured digest.
2. Write predictions before acting
Record at least these predictions in
ch04-evidence/predictions.txt before running the lab:
- Pulling the source tag may add a local reference/content, but will not create a running container.
- Creating a disposable alias will add another reference without changing the underlying local Image ID.
- Running by the captured RepoDigest will create a container whose image identity matches the locally selected config/Image ID.
-
Removing the checkpoint container and alias will not require
deleting the upstream
busybox:1.37.0reference or broad shared content.
3. Preflight and environment evidence
mkdir -p ch04-evidence
SOURCE='busybox:1.37.0'
ALIAS='devops-academy-image-id:checkpoint'
NAME='devops-academy-ch04-checkpoint'
{
date -u +'%Y-%m-%dT%H:%M:%SZ'
docker context show
docker version
docker info
docker buildx version
docker buildx ls
} > ch04-evidence/environment.txt 2>&1
docker version
If the final command cannot reach the daemon, stop. The checkpoint requires a functioning disposable/local Docker environment. Do not switch to an unknown remote context just to make the lab run.
4. Capture registry-side identity before local conclusions
docker buildx imagetools inspect "$SOURCE" \
> ch04-evidence/registry-inspect.txt
docker buildx imagetools inspect --raw "$SOURCE" \
> ch04-evidence/registry-top-level.json
In registry-inspect.txt, identify the top-level
digest/media type and your host platform's child manifest if an
index is present. Do not edit the captured output to make values
“match” another machine.
5. Pull, then capture the repository digest and local image
docker pull "$SOURCE" | tee ch04-evidence/pull.txt
docker image inspect "$SOURCE" > ch04-evidence/local-image.json
docker image inspect "$SOURCE" \
--format 'ID={{.Id}}\nRepoDigests={{json .RepoDigests}}\nOS={{.Os}} Arch={{.Architecture}}\nRootFS={{json .RootFS}}\nCreated={{.Created}}' \
| tee ch04-evidence/local-summary.txt
PINNED=$(docker image inspect "$SOURCE" --format '{{index .RepoDigests 0}}')
printf '%s\n' "$PINNED" | tee ch04-evidence/pinned-reference.txt
test -n "$PINNED"
The checkpoint uses the captured PINNED value from this
environment. A hard-coded digest in course prose would undermine the
lesson because published tags and platform indexes can evolve.
6. Capture history and explain its limits
docker image history --no-trunc "$SOURCE" \
> ch04-evidence/history.txt
Add a note to your dossier: history is useful for build-step narrative, but exact layer descriptors belong to the manifest and rootfs DiffIDs belong to the image config/local inspection. A metadata-only history row can exist without a filesystem layer.
7. Create an alias and verify reference behavior
docker tag "$PINNED" "$ALIAS"
{
docker image inspect "$SOURCE" --format 'source={{.Id}}'
docker image inspect "$ALIAS" --format 'alias={{.Id}}'
docker image ls --digests "$ALIAS"
} | tee ch04-evidence/alias.txt
The two IDs should match. That is evidence that the alias is another name for the same local config/image content, not a byte-for-byte duplicate stored independently.
8. Re-pull by digest and run the checkpoint container
docker pull "$PINNED" | tee ch04-evidence/digest-pull.txt
docker run --name "$NAME" "$PINNED" sh -c \
'echo checkpoint-ok; uname -s; uname -m' \
| tee ch04-evidence/container-output.txt
docker inspect "$NAME" \
--format 'Container={{.Id}}\nConfigImage={{.Config.Image}}\nLocalImageID={{.Image}}\nExit={{.State.ExitCode}}\nStatus={{.State.Status}}' \
| tee ch04-evidence/container-summary.txt
Interpret every green state precisely. The digest pull proves retrieval of that immutable repository reference. The container exit code proves the small command completed. Neither proves SBOM completeness, signature trust, vulnerability status, or production service health.
9. Required dossier map
| Question | Evidence file | Identity/state to extract |
|---|---|---|
| Which daemon/context did this? | environment.txt |
Context, client/server versions, OS/arch, storage/image-store clues, Buildx. |
| What did the registry publish? |
registry-inspect.txt,
registry-top-level.json
|
Index/manifest media type, top-level digest, platform descriptors. |
| What did the daemon materialize? |
local-image.json,
local-summary.txt
|
Image ID/config, RepoDigests, selected platform, DiffIDs. |
| What immutable reference was used? | pinned-reference.txt |
Repository-qualified digest reference. |
| What did the container run? | container-summary.txt |
Container ID, original config reference, local image ID, exit status. |
| What was cleaned? | cleanup.txt |
Exact lab container/alias removal and absence afterward. |
10. Independent verification checklist
- The top-level registry object type is identified from evidence, not guessed.
- The host platform is recorded and a matching platform descriptor is identified when an index exists.
- The local Image ID and repository digest are both present and not labeled as interchangeable.
- At least one rootfs DiffID is recorded and correctly described as uncompressed changeset identity.
- The digest-pinned pull used the captured repository reference.
-
The container's
.Imagematches the local image/config identity expected for the selected content. - No secret, production endpoint, daemon data-root mutation, broad prune, or registry publication occurred.
11. Guarded cleanup and after-state
{
docker inspect "$NAME" --format 'removing-container={{.Id}}' 2>/dev/null || true
docker rm "$NAME" 2>/dev/null || true
docker image inspect "$ALIAS" --format 'removing-alias={{.Id}}' 2>/dev/null || true
docker image rm "$ALIAS" 2>/dev/null || true
echo 'container-after:'
docker ps -a --filter "name=^/${NAME}$"
echo 'alias-after:'
docker image ls "$ALIAS"
echo 'source-still-observable:'
docker image inspect "$SOURCE" --format '{{.Id}}' 2>/dev/null || true
} | tee ch04-evidence/cleanup.txt
Keeping the source image is intentional because the checkpoint cannot prove it was created solely for this lab. Cleanup is scoped to objects with checkpoint-specific names.
12. Operational review and Chapter 05 handoff
You now have an evidence chain from a mutable human-readable reference to registry content identity, selected platform, local config/Image ID, rootfs DiffIDs, container image identity, and digest-pinned retrieval. That is the foundation for reproducible promotion and incident analysis.
Chapter 05 moves from image identity to container lifecycle state: create, run, start, stop, restart, remove, exec, attach, and inspect. Keep the Chapter 04 distinction in mind: an image can exist without any container, a container object can exist without a running process, and removing a container does not inherently delete the image content it referenced.
Knowledge check
Why does the checkpoint save registry evidence before relying on local image inspection?
Registry and local-store states are different. Registry evidence establishes the published index/manifest graph; local inspection shows what the active daemon materialized for its platform.
If the alias and source show the same Image ID, what changed when you tagged the alias?
A new human-readable reference was added to existing local image content. The underlying config/image identity did not change.
Why is the digest in pinned-reference.txt stronger
rollback evidence than
busybox:1.37.0 alone?
The digest identifies exact published content. The tag is a mutable lookup name that could later resolve differently.
A digest-pinned container exits 0. Does that prove the image is secure?
No. It proves the executed command succeeded for that content/platform. Security requires separate evidence such as vulnerability analysis, provenance, signatures, runtime controls, and policy.
Why does checkpoint cleanup leave the source image reference alone?
The lab cannot prove that upstream reference was created only for the checkpoint; it may be shared with other work. Cleanup removes only checkpoint-owned names.
Official references and version notes
- Docker: What is an image? — image/layer fundamentals and local image inspection.
- docker image pull — content-addressable image storage, shared layers, pull digests, and pulling by digest.
- docker image inspect — local image metadata, IDs, RepoDigests, rootfs data, and platform-aware inspection.
- docker image ls — repository/tag presentation, image IDs, and digest display.
- docker image history — build-history presentation and platform selection.
- docker buildx imagetools inspect — registry-side image index/manifest inspection without assuming the local store contains every platform.
- containerd image store with Docker Engine — Engine 29 fresh-install default, snapshotters, multi-platform local storage, and upgrade/userns-remap caveats.
- Docker storage drivers — layer sharing, copy-on-write context, history examples, and classic storage-driver behavior.
- OCI Image Specification v1.1.1 — current stable OCI image-format release used as the chapter's standards baseline.
- OCI image manifest — config descriptor, ordered layer descriptors, media types, and single-image/platform semantics.
- OCI image index — higher-level descriptor set used for multi-platform publication.
- OCI image configuration — runtime configuration, rootfs DiffIDs, history, and ImageID-related content.
- OCI content descriptors — media type, digest, size, platform, and content-verification semantics.
Verified 2026-09-21: Docker Engine 29.8.1 remains
the current Engine 29 patch line used by this course baseline.
Fresh Docker Engine 29 installations use the containerd image
store by default, while upgraded older daemons can retain the
classic storage-driver store; userns-remap is a
documented exception. OCI Image Specification
v1.1.1 is the current stable release. The
mandatory lab uses the Docker Official Image
busybox:1.37.0 only as a small human-readable
starting reference, then captures and uses the registry-provided
digest at run time. Always record the actual daemon, storage
backend, platform, Buildx version, media types, and resolved
digests observed on the learner's system.
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.