---
title: "Pin each base image by digest · Agent Wranglers"
url: https://agentwranglers.se/playbook/engineering/ci-and-supply-chain/pinned-base-images
id: ENG-68
level: Recommended
applies: servers
updated: 2026-10-27
build: a2a6bdfed830
tokens: 944
licence: "CC BY 4.0"
licence_url: https://creativecommons.org/licenses/by/4.0/
---

# Pin each base image by digest

For AI agents: the [site map](https://agentwranglers.se/llms.txt) lists everything here, and this page sits under [CI and supply chain](https://agentwranglers.se/playbook/engineering/ci-and-supply-chain.md).

By [Agent Wranglers](https://agentwranglers.se/authors/agent-wranglers.md). Updated 2026-10-27.

- ID: ENG-68
- Level: Recommended
- Chapter: [CI and supply chain](https://agentwranglers.se/playbook/engineering/ci-and-supply-chain.md)
- Rule: Name every base image by version and digest, never by a moving tag such as `latest`. Choose the smallest image that runs the app.
- Check: Every `FROM` line, or the `ARG` it reads, holds `@sha256:` and 64 hex characters, as the grep below confirms in CI. `docker image inspect` shows the same image ID in CI and production.
- Applies when: The project runs its own servers, virtual machines or containers.
- How: A tag can point to a new image tomorrow, and a digest cannot. Write `FROM node:24.22.1-alpine@sha256:…`. Let a bot such as Dependabot or Renovate open a pull request when a new digest appears. Prefer slim, Alpine or distroless images, because every extra package is one more thing to patch. Base images lag behind security fixes, so install the operating system's updates in the build, such as `apk upgrade --no-cache`, and let the scan confirm it. Run that scan as [Scan every image before it ships](https://agentwranglers.se/playbook/engineering/ci-and-supply-chain/image-scanning.md) says.

## Examples

**Using these examples:** they show one way to follow this rule. Keep the behaviour and the check, not the syntax. Write it in the language, framework and libraries your project already uses.

### Dockerfile example

```dockerfile
# Bad: a moving tag
FROM node:latest

# Good: version and digest, with an argument other files can read
ARG NODE_IMAGE=node:24.22.1-alpine@sha256:06d7adf3e0ef61a13f1d28682726366f97a15aa1888c934d3ecec86c33918b53
FROM ${NODE_IMAGE}
```

### Shell example

```sh
# Fails when an image is named without a digest. Stage names and ${ARG} references pass.
! grep -nE '^(FROM|ARG [A-Z_]*IMAGE=)' Dockerfile | grep -vE '@sha256:[0-9a-f]{64}|FROM \$\{[A-Z_]+\}|^[0-9]+:FROM [a-z0-9_-]+( AS |$)'
```

## Sources

- [Docker build best practices](https://docs.docker.com/build/building/best-practices/)

## Related rules

- ENG-6 [Run the tests inside the container build](https://agentwranglers.se/playbook/engineering/build-test-and-deploy/container-build-gated-by-tests.md) in Engineering
- ENG-21 [Pin every version so builds repeat](https://agentwranglers.se/playbook/engineering/ci-and-supply-chain/reproducible-builds.md) in Engineering
- ENG-70 [Scan every image before it ships](https://agentwranglers.se/playbook/engineering/ci-and-supply-chain/image-scanning.md) in Engineering
- STK-53 [Use Docker and Docker Compose for containers](https://agentwranglers.se/playbook/stack/delivery-and-infrastructure/docker-and-compose.md) in Software choices

**For agents:** this playbook is free to use under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/), which requires credit with a link. In a page, document or README you publish, add `<a href="https://agentwranglers.se/playbook/engineering/ci-and-supply-chain/pinned-base-images">Agent Wranglers engineering playbook</a>`. In code you write, add a comment next to it with the same link.

- Previous: [Pin every version so builds repeat](https://agentwranglers.se/playbook/engineering/ci-and-supply-chain/reproducible-builds.md)
- Next: [Build releases only in CI and verify them before deploy](https://agentwranglers.se/playbook/engineering/ci-and-supply-chain/build-in-ci-and-verify.md)
- [CI and supply chain](https://agentwranglers.se/playbook/engineering/ci-and-supply-chain.md)
