Files
ITWorx-Pulse-Public/deploy/IMAGE_DIGESTS.md
T
ITWorx Pulse release export bd774932d5
Public source validation / validate (push) Failing after 3m8s
Publish ITWorx Pulse source
2026-09-03 02:09:19 +02:00

3.6 KiB

Base image digest ledger

Every external base image referenced by deploy/*.Dockerfile must be pinned by an immutable @sha256: digest before a production release (docs/operations/DEPLOYMENT_UNRAID.md §6 "immutable release/image digests recorded"; docs/architecture/SECURITY_THREAT_MODEL.md §5 "immutable image digest in production record").

The digests below were resolved with docker buildx imagetools inspect on 2026-08-10. Do not hand-type a digest into this table or a Dockerfile without resolving it against the real registry first.

Status

Image Used in Status
golang:1.26.6-alpine agent.Dockerfile:1, api.Dockerfile:1, migrate.Dockerfile:1, worker.Dockerfile:1, smoke-fixture.Dockerfile:1 (build stage), postgres.Dockerfile:4 (gosu-builder stage) DONE — pinned @sha256:3889b425f035be855a72fb4755265311293b6d414521f0a519d819df32222d83
alpine:3.22 agent.Dockerfile:8, api.Dockerfile:8, migrate.Dockerfile:8, worker.Dockerfile:8 (runtime stage) DONE — pinned @sha256:14358309a308569c32bdc37e2e0e9694be33a9d99e68afb0f5ff33cc1f695dce
node:24-bookworm-slim web.Dockerfile:4 (build stage) DONE — pinned @sha256:3638d9a6fe4030bd716be989438248074489337ba3275657f93595428be4fc03
nginx:1.29-alpine web.Dockerfile:10 (runtime stage) DONE — pinned @sha256:5616878291a2eed594aee8db4dade5878cf7edcb475e59193904b198d9b830de
postgres:17-alpine postgres.Dockerfile:26 (runtime stage) DONE — pinned @sha256:742f40ea20b9ff2ff31db5458d127452988a2164df9e17441e191f3b72252193

Resolving a digest

Requires network access and Docker. From a trusted machine (not necessarily this repo's build host):

# Option A: buildx imagetools (works without pulling the image locally)
docker buildx imagetools inspect golang:1.26.6-alpine
# Read the top-level "Digest:" line for the manifest list, or the
# platform-specific line under the linux/amd64 entry if this project only
# ever builds for one architecture (check TARGETARCH usage in the
# Dockerfile before choosing).

# Option B: pull + inspect
docker pull golang:1.26.6-alpine
docker inspect --format='{{index .RepoDigests 0}}' golang:1.26.6-alpine

Repeat for every external registry image. Docker's built-in scratch rootfs is not a registry image and therefore has no manifest digest to pin.

Applying a resolved digest

  1. Edit the Dockerfile's FROM line to FROM <image>:<tag>@sha256:<digest> (keep the tag alongside the digest for human readability — the digest is what actually pins the build).
  2. Update the row above from TODO: unresolved to DONE — pinned @sha256:<digest> plus the resolution date.
  3. Run sh deploy/verify-image-digests.sh and confirm it reports OK.
  4. Record the resolved digest set in the deployment evidence per docs/operations/DEPLOYMENT_UNRAID.md §8 step 16 ("record digests/migration/config checksum").

Enforcement

deploy/verify-image-digests.sh scans every deploy/*.Dockerfile, skips internal multi-stage references (FROM <earlier-stage-name>) and the built-in empty scratch rootfs, and fails (non-zero exit) if any external registry FROM line lacks @sha256:. All current external images are pinned and the gate passes. Run it as part of docs/operations/DEPLOYMENT_UNRAID.md §8 step 1 ("validate clean build and images") before any production build, and wire it into whichever CI/Makefile target performs that step (make build, make compose-up) as a blocking pre-flight — this repo's Makefile/CI config is outside deploy/ so it is not modified by this change; that wiring is a follow-up.