Pin a Base Image by Digest
Look up a base image digest, pin it in the FROM line, check the build used it and plan how to update it. After this, your builds are repeatable without missing security fixes.
FROM python:3.14-alpine can give you a different image next month, because the publisher moves the tag when they rebuild. Pinning the digest gives you the exact same base every time. This page finds the digest, pins it, and shows how to update it on purpose. Run on Docker Desktop 4.85.0 (Engine 29.6.2) on 21 October 2026. Your digests will differ if the image has been rebuilt since then.
Find the digest
docker buildx imagetools inspect python:3.14-alpine --format "{{json .Manifest.Digest}}"
"sha256:f6a589d43c42b9e7f7dc67a12d37132491f362859a5d750607710cc56da3bc72"
This is the digest of the multi-platform index, which is what you want. It works on Intel and ARM machines alike. If you already pulled the image, docker image inspect python:3.14-alpine --format "{{index .RepoDigests 0}}" shows the same value.
Pin it, and keep the tag
FROM python:3.14-alpine@sha256:f6a589d43c42b9e7f7dc67a12d37132491f362859a5d750607710cc56da3bc72
CMD ["python", "-c", "import sys; print(sys.version.split()[0])"]
Set-Location digest-demo
docker build -q -t digest-app . | Out-Null
docker run --rm digest-app
3.14.8
When both are written, Docker uses the digest and ignores the tag. Keep the tag anyway. It tells the next person what sha256:f6a5... is meant to be, and update tools use it to find newer digests.
Check that a build used the pin
The plain build log names the exact base image it used:
docker build --no-cache --progress=plain -t digest-app . 2>&1 | ForEach-Object { "$_" } | Select-String "\[1/1\] FROM" | ForEach-Object { $_.Line -replace '^#\d+ ', '' } | Select-Object -First 1
[1/1] FROM docker.io/library/python:3.14-alpine@sha256:f6a589d43c42b9e7f7dc67a12d37132491f362859a5d750607710cc56da3bc72
If you see the tag without the digest there, the Dockerfile you built is not the one you think.
Update it on purpose
A pin never updates by itself, so security fixes from the publisher never reach you unless you move it. Pick one way and write it down:
- A bot. Dependabot (with the
dockerecosystem) and Renovate both readFROM image:tag@sha256:...lines and open a pull request when the tag points at a new digest. Your build and tests run on that pull request before anyone merges it. I did not set up either bot for this page. - By hand on a schedule. Run the
imagetools inspectcommand above, paste the new digest, build, test, commit. Put it in the calendar, for example every two weeks, and right away when a serious CVE is announced for your base image.
⚠ Warning: A digest pinned a year ago is a year of missed security fixes. Pinning without updating is worse than not pinning, because it looks safe.
If the build fails after pinning
not found: the digest is wrong, usually a copy and paste mistake, or the publisher removed that old image. Look it up again.- Wrong platform: you pinned the digest of one platform's image instead of the index. Use the
imagetools inspectdigest. - Different Python version than you expected: the tag in the line is only a note. The digest decides, so check what the digest really contains.
Related course: Docker Advanced.
About
Look up a base image digest, pin it in the FROM line, check the build used it and plan how to update it. After this, your builds are repeatable without missing security fixes.
- Responsible
- John G
- Last Update
- 08/08/2026
- Reading Time
- 3 min
Reviews
Sign in to write a reviewComments (0)
Sign in to commentNo comments yet.