19.1.3.3 Pull Digest Selection
A focused guide to Pull Digest Selection, connecting core concepts with practical Docker and container operations.
Pull digest selection addresses the practical question of how to actually obtain the correct digest value to pull or reference in the first place, since a digest is a long, opaque hash with no memorable structure, and several distinct commands serve different purposes for retrieving one depending on whether the goal is checking an already-pulled local image, querying a registry without pulling at all, or capturing a digest programmatically as part of a CI pipeline.
Retrieving the digest of an already-pulled local image
For an image already present locally, its digest is retrieved directly through inspection without needing any further network activity:
docker inspect my-api:1.4.2 --format '{{index .RepoDigests 0}}'
my-api@sha256:3f29a8c1d8e2b4f6a9c7d5e8b1f3a6c9d2e5f8b1a4c7d0e3f6a9c2d5e8b1f4a7
This is the appropriate command when the actual question is "what digest does this image I already have locally correspond to," useful for recording exactly what was pulled or built as part of a deployment or audit record.
Querying a registry's digest without pulling
When the goal is checking what digest a tag currently points to in a registry, without actually downloading the full image content, docker manifest inspect or the buildx equivalent retrieves just the manifest information directly:
docker manifest inspect my-api:1.4.2
docker buildx imagetools inspect my-api:1.4.2 --format '{{json .Manifest}}'
This is considerably faster and more bandwidth-efficient than pulling the full image purely to check its current digest, particularly useful for a script that needs to periodically check whether a tag's target has changed without actually needing the full image content every single time it checks.
Distinguishing manifest list digest from platform-specific digest
For a multi-architecture image, the digest reported can refer either to the overall manifest list's own digest or to one specific platform variant's individual digest within that list, and confusing the two produces a reference that resolves to a meaningfully different scope of content:
docker buildx imagetools inspect my-api:1.4.2
Name: my-api:1.4.2
Digest: sha256:abc123... (manifest list digest)
Manifests:
Name: my-api:1.4.2@sha256:def456... Platform: linux/amd64
Name: my-api:1.4.2@sha256:789abc... Platform: linux/arm64
Pinning a deployment to the top-level manifest list digest preserves correct multi-architecture resolution on pull; pinning to one specific platform's individual digest instead fixes the deployment to that one architecture only, which is the same distinction covered for base image pinning generally, equally relevant when selecting which digest to actually use for any pull-time reference.
Capturing a digest programmatically in a CI pipeline
For a pipeline needing to record exactly which digest a given build produced, capturing it immediately after the build or push step, rather than attempting to look it up again separately afterward, avoids any possibility of the underlying tag having changed in the brief interim between the build and the lookup:
docker build -t my-api:1.4.2 .
DIGEST=$(docker inspect my-api:1.4.2 --format '{{index .RepoDigests 0}}')
echo "Built digest: $DIGEST"
docker push registry.example.com/my-api:1.4.2
DIGEST=$(docker inspect registry.example.com/my-api:1.4.2 --format '{{index .RepoDigests 0}}')
Capturing the digest specifically after the push, rather than before, is important since the local pre-push image inspection may not yet reflect the registry-assigned digest in every configuration; confirming the digest reported matches what the registry itself now has recorded for that reference is the more reliable, accurate approach.
Selecting a digest for cross-environment promotion
When promoting a build from one environment to the next, capturing and explicitly carrying forward the exact digest produced in the earlier stage, rather than re-resolving a tag at each subsequent stage, ensures every stage genuinely deploys the identical content, the same digest-propagation principle covered for production deployment pipelines generally, applied specifically here to the question of which command actually retrieves that digest value to carry forward in the first place.
echo "$DIGEST" > artifact-digest.txt
DIGEST=$(cat artifact-digest.txt)
docker pull "registry.example.com/my-api@$DIGEST"
Common mistakes
- Pulling an entire image purely to check its current digest, when
docker manifest inspector the buildx equivalent retrieves the same information without the full download. - Confusing a manifest list's overall digest with one specific platform variant's individual digest, producing a pull-time reference with an unintended, narrower scope.
- Attempting to look up a build's digest separately and after the fact, rather than capturing it immediately following the build or push step where it is reliably, immediately available.
- Capturing a digest before pushing rather than after, missing a scenario where the local pre-push inspection does not yet reflect the registry's own assigned digest.
- Re-resolving a tag at each stage of a deployment pipeline rather than capturing and explicitly carrying forward the exact digest from the build stage through every subsequent stage.
Pull digest selection depends on matching the right command to the actual question being asked, local inspection for an already-pulled image, manifest inspection for a registry query without pulling, and careful attention to manifest-list versus platform-specific scope, all of which together ensure the digest actually captured and used for any subsequent pull or pin genuinely represents the intended content.