Safeguard
Developer Tools•

Should you pin apt package versions in a Dockerfile?

Pinning makes builds repeatable but can freeze in a vulnerable version or break when a version leaves the archive. Weigh both and pick a refresh routine.

Safeguard Security Team
4 min read

Pin only when repeatability matters more than automatic fixes, and pair every pin with a scheduled rebuild. Docker's guidance says pinning forces the build to fetch a specific version, but it also means you stop receiving fixes for that package until you change the pin.

What Docker says

Docker's build best practices state that version pinning forces the build to retrieve a particular version regardless of what is in the cache, and show a pattern like a package name followed by a version with a wildcard. They also say to combine apt-get update with install in the same RUN instruction so stale lists do not defeat the pin.

The same page makes a related point about base images: pinning a digest gives supply chain integrity, but you opt out of automated security fixes, so use an update tool to move the digest.

The tradeoff in a table

ApproachGainCost
No pinsYou get new fixes on every rebuildTwo builds of the same commit can differ
Pin exact versionSame bits every time while the version is availableYou own every update. Old versions may disappear from the mirror and break the build
Pin with a wildcard on the minor lineReceives patch level updates within a lineStill moves; a bad patch can slip in
Pin the base image digestStrong reproducibility for the OS layerFixes arrive only when you bump the digest

What pinning does and does not protect

Pinning protects you from surprise changes. It does not protect you from known bad versions. If you pin a package that later receives a security advisory, your image stays vulnerable until someone edits the Dockerfile. Pinning without a refresh routine turns reproducibility into patch debt.

The reverse risk also exists. Debian and Ubuntu archives replace package versions as fixes ship, so an exact pin can start failing the build when the old version is removed. A failed build is at least visible, but it often prompts a rushed edit.

For true reproducibility you need a fixed source of packages as well as a fixed version. See what is snapshot.debian.org and when should you use it.

A policy that works

  1. Pin the base image by digest and let a bot propose updates, as in should a bot update your container base image.
  2. Do not pin ordinary OS packages unless you have a reason you can write down.
  3. If you pin, put a comment with the reason and the date next to it.
  4. Rebuild on a schedule using the pull flag so you receive a fresh base, and the no cache flag when you need every step to rerun, as Docker advises.
  5. Scan the result every time, because a clean build is not a clean image.

Try it yourself

Click through the scan and find an OS package finding, then ask whether a pin would have prevented it or locked it in.

Click through it at your own pace, or open it full screen.

Quick check

Does pinning make my image more secure?

Not by itself. It makes builds repeatable. Security depends on how often you move the pin forward.

What is the downside of pinning a base image digest?

Docker notes you opt out of automated security fixes, so you need a process to update the digest.

Safeguard scans container images and dependencies and can raise fix pull requests, which are off by default and need your approval. Try a free scan at gold.safeguard.sh/scan.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.