iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
A Git commit fixes the source revision, not every input a Docker build consumes. A base-image tag, package repository, target platform, build argument, builder configuration, or timestamp can change between runs and produce a different image digest or contents. Compare the two builds’ digests and metadata first, then trace which resolved input or build behavior differs.
What a commit does—and doesn’t—fix
A commit identifies a snapshot of version-controlled source. It does not freeze every external value used while building an image. For example, a Dockerfile may refer to a mutable base-image tag or install packages from a repository whose contents change over time. Those references can resolve differently on separate builds even when the Dockerfile and commit are unchanged. A study of Docker build reproducibility identified floating versions among the causes of non-reproducible outputs; its results describe its sample and setup, not every Docker build. The study reported that 78.7% of buildable Dockerfiles in its sample remained non-reproducible and that infrastructure changes improved bitwise reproducibility by 18.6%.
How to compare the two builds
- Compare the exact digests and platforms. Record each output digest and determine whether it identifies a multi-platform manifest list/index or a platform-specific image. Confirm that both builds requested the same target platform; different hardware targets can produce different image variants. See Docker’s multi-platform build documentation.
- Compare build configuration and provenance. Check the Dockerfile frontend, BuildKit and Buildx versions, build arguments, context inputs, and source references. Build information can record frontend attributes, pinned references, build arguments, and the output digest. Docker documents build attestations and metadata.
- Resolve the base-image references. A tag can point to different content over time. Compare the resolved image digest for each build, not just the tag written in the Dockerfile. Docker’s build-information example shows source references recorded with pins. Build metadata documentation
- Check package installation and lockfiles. Look for commands that fetch current repository state, and compare lockfiles and resolved package versions. A cached
RUNinstruction is not automatically re-executed on every build, so establish whether each build reused the layer or ran the command again. Docker also notes that secret contents are not included in the cache checksum. Docker’s cache invalidation guidance - Inspect timestamps. Compare layer and image-configuration timestamps. Docker supports
SOURCE_DATE_EPOCHto set timestamps; a fixed value can help avoid timestamp-only differences. Changing this value between builds invalidates the cache forWORKDIRand subsequent instructions. Cache invalidation documentation explains the cache effect; Docker’s BuildKit v0.11 article discusses timestamps in image outputs. - Compare builder and image-store setup. If you expected attestations, check the builder driver and image-store configuration: attestation behavior differs across setups. Docker’s attestation documentation
- Separate filesystem changes from metadata changes. If the digests differ but extracted files appear equivalent, inspect layers and image metadata independently. Digest inequality establishes that the encoded image differs; it does not by itself identify the changed input.
Build inputs worth pinning or standardizing
- Base images and dependencies: Pin base images by digest and use explicit dependency versions. Prefer lockfiles and versioned or snapshot repositories where available, and verify fetched artifacts.
- Build configuration: Keep the target platform, build arguments, Dockerfile frontend, and builder configuration consistent across runs.
- Timestamps: Set
SOURCE_DATE_EPOCHconsistently. A fixed value supports repeatability without needlessly invalidating cache; a changing commit timestamp can invalidate cache as commits change. Docker explains this interaction. - Evidence in CI: Record build provenance and output digests so later comparisons have concrete inputs to inspect. Whether attestations are generated and retained depends on the builder and image store. Docker’s documentation
What cache and timestamps can explain
Cache reuse can make two builds behave differently if one reuses a layer while another runs its instruction against newer external state. Docker does not automatically invalidate a cached RUN merely because a package repository changed, and secret values are excluded from the cache checksum. Timestamps can also affect output even when file contents appear unchanged; Docker specifically warns that changing SOURCE_DATE_EPOCH invalidates cache for WORKDIR and every later instruction. Treat cache history and timestamps as evidence to compare, not as proof of a cause on their own.
What can be concluded from the digest?
Two different image digests mean the outputs are not identical in the way those digests represent them. They do not reveal whether the difference came from filesystem contents, configuration, timestamps, platform selection, provenance, or another build input. Without the two build logs, Dockerfile, resolved references, platforms, and builder versions, no single cause can be assigned. A useful comparison therefore pairs each digest with its platform and recorded build inputs, then narrows the difference layer by layer.
Quick Recap
Best Value
Rank #4
Rank #3
#1 Best Overall
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

