Search across all documentation pages
sha256 content hash instead of a mutable tag like latest or 1.22.@sha256:...), tag mutability, rebuild cadence, reproducibility, and automated bump PRs.Resolve the tag you use to its current digest.
docker pull python:3.13-slim
docker inspect --format='{{index .RepoDigests 0}}' python:3.13-slimCopy the returned digest into your Dockerfile FROM line.
FROM python:3.13-slim@sha256:2f1e...c9abCommit that Dockerfile. Every build from now on uses exactly those bytes until you change the digest on purpose.
Keep the human-readable tag as a comment so reviewers know what the digest represents.
# python:3.13-slim as of 2026-07-15
FROM python:3.13-slim@sha256:2f1e0b3a5c7d9e11223344556677889900aabbccddeeff00112233445566c9ab
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
USER 65532:65532
ENTRYPOINT ["python", "-m", "app"]Enforce the pin in CI so no one sneaks in a floating tag.
# Fail the build if any FROM uses a tag without a digest
grep -E '^FROM ' Dockerfile | grep -qv '@sha256:' && {
echo "Base image not pinned by digest"; exit 1; }Automate the bump so pinning does not mean staleness. Renovate or Dependabot opens a PR when a new digest is published.
{
"extends": ["config:recommended"],
"docker": { "pinDigests": true }
}Renovate rewrites the @sha256: value and updates the comment, and your CI scan runs against the new digest before merge.
A tag is a mutable label in the registry. The maintainer can push new bytes to python:3.13-slim at any time, so two builds a week apart can differ silently.
That is convenient for getting patches but terrible for reproducibility and incident forensics. You cannot answer "what exactly was running" from a tag alone.
The digest is a sha256 hash of the image manifest, which in turn references the config and layer digests. Change one byte in any layer and the manifest digest changes.
Because the registry stores content addressed by that hash, @sha256:... can never point at different bytes. It is immutable by construction.
Pinning solves reproducibility. It does nothing for security on its own.
The base maintainer patches a CVE by publishing new bytes under the same tag with a new digest. If your Dockerfile still names the old digest, you never receive the fix.
So the pattern is two-part: pin by digest for reproducibility, and run automated digest bumps plus scheduled rebuilds for security. One without the other is a half measure.
A tag on a multi-arch base points at an image index whose digest covers all platforms. Pinning that index digest keeps linux/amd64 and linux/arm64 builds consistent.
Avoid pinning a single platform's child manifest unless you build for exactly one architecture.
Pinning and then never rebuilding. The most common failure. The image is reproducible and quietly months behind on patches. Schedule a weekly rebuild or nightly Renovate run.
Copying a digest by hand and typo-ing it. A wrong hash fails the pull with a manifest error. Always resolve it with docker inspect or let Renovate write it.
Pinning a platform manifest instead of the index. Cross-arch builds break or silently pull the wrong platform. Pin the index digest that the tag resolves to.
Assuming the digest survives a re-push. If you mirror images into a private registry, the digest is preserved only if you copy by digest (for example with crane cp), not by re-tagging.
Forgetting the readable comment. A bare @sha256: line is unreviewable. Keep the tag and date in a # comment above it.
Floating minor tag (python:3.13). Simple and auto-patches, but non-reproducible and can break builds without warning. Fine for local dev, weak for production.
Digest pin plus Renovate (recommended). Reproducible and patched, at the cost of a bot config and a steady stream of small PRs to review and merge.
Vendored base in a private registry. Mirror an approved, pre-scanned base and pin its digest. Best for regulated environments; adds a mirroring pipeline to maintain.
Rebuild-from-source bases (for example Wolfi/Chainguard). Frequently rebuilt minimal bases with few CVEs. Pin their digests too and rely on their fast patch cadence.
Does pinning by digest make my image more secure? Not by itself. It makes builds reproducible. Security comes from rebuilding onto patched digests on a cadence.
How do I find the digest for a tag?
Pull the image and read RepoDigests with docker inspect, or query the registry with a tool like crane digest.
How often should I bump digests? Weekly is a common baseline, with immediate bumps when a Critical CVE in the base is disclosed.
Should application images also be pinned? Yes, when one image bases on another internal image. Pin that internal base by digest for the same reproducibility guarantee.
Can admission control require digests?
Yes. A ValidatingAdmissionPolicy can reject any pod whose image reference lacks @sha256:, forcing digests cluster-wide.
Does this affect the node runtime? Only indirectly. You build and pin with Docker, and containerd via the CRI pulls the pinned digest when it runs the pod.
Stack versions: This page was written for Kubernetes 1.36.2, Docker Engine 29.6.1 (BuildKit default), containerd (CRI runtime on nodes), Helm 3, Compose v2, Argo CD (latest - verify at build), and Gateway API (GA - verify controller support at build).
Reviewed by Chris St. John·Last updated Jul 16, 2026