Skip to content
CommonLayer
Documentation menu
On this page

ADR-0011: Images built from verified upstream source onto a from-scratch root

Status: Accepted (plan decision D11). Implemented for the base image, the project template, nginx, PostgreSQL and Valkey.

Context

Images built FROM a distribution image inherit its package manager, shells and network tools, and their versions follow the distribution, not upstream. Distroless images drop the package database, which makes scanners blind to what is inside.

Decision

  • The base image (projects/base) installs a minimal Alpine package set into an empty root with apk --root, removes the package manager and copies that root into a scratch stage. The apk database is kept so that scanners identify packages.
  • Applications are built from the upstream release tarball, verified by SHA-256 (and by OpenPGP signature where upstream signs, as nginx does), in a build stage; only the results are copied into the final stage.
  • The final image has no package manager, no compiler, no curl or wget, runs as 10001:10001, and works with a read-only root filesystem.

Consequences

  • Exact upstream versions are possible, independent of Alpine's package versions.
  • Runtime libraries come from Alpine packages added by image/build/add-runtime-packages.sh, which merges the apk database without a package manager in the final image.
  • linux/amd64 builds are built and tested locally; linux/arm64 builds are expected to run on native CI runners and have not been executed yet.
  • BusyBox had to be rebuilt to remove network applets properly (ADR-0020).

Amendment, 2026-11-10

  • linux/arm64 has still not been built anywhere: the repository is private, and the workflows build arm64 only when CL_ARM64_RUNNER names a runner or the repository is public (.github/scripts/platforms.sh, WP-70d). The release workflows refuse to release without arm64.