The v0.75.0 release was blocked by four HIGH CVEs in the webapp image. The cause is structural, not a stale pin.
The defect
webapp/Dockerfile pins FROM nginx:stable-alpine@sha256:97d490c… and runs apk add --no-cache bash sed grep curl with no apk upgrade. Alpine shipped openssl 3.5.8-r0 and expat 2.8.4-r0; neither can reach the image by any path that exists in this repository:
- Renovate updates a digest only when upstream publishes a new one.
nginx:stable-alpine still resolves to that exact digest today.
- docker-library documents that Alpine-based official images are "subject to their own maintenance schedule" and rebuilds cascade only to currently-listed tags.
So OS packages in every digest-pinned image here are unpatchable by construction. Verified: that digest carries 4 HIGH; adding apk upgrade --no-cache takes it to 0.
Scope
webapp/Dockerfile — apk upgrade --no-cache ahead of the existing apk add.
docker/agents/pi/Dockerfile — the identical latent failure: digest-pinned node:*-slim, apt-get install, no upgrade. It would block the release after this one. Fix it in the same change.
docker/postgres/Dockerfile — the tag floats, so it picks up docker-library rebuilds. Lower priority; add for consistency.
- Worth 60 seconds first:
security/release-images.json already tracks a newer nginx-alpine digest (sha256:db35bfc6…) than webapp/Dockerfile pins. Scan it — if clean, repoint the base as well.
There is no reproducibility trade-off
apk add is already unversioned against the live index, so build reproducibility does not exist to lose. OpenSSF Scorecard's pinned-dependencies check has a closed enum of eight dependency types containing no package manager, so apk upgrade carries no penalty. Docker deleted the anti-upgrade guidance in 2021; hadolint removed DL3005 in 2023.
Verification
The nginx official image installs nginx from nginx.org via a one-shot apk add -X <url> repository that is not persisted, so apk upgrade draws from Alpine main/community only. Confirm nginx -v is unchanged and the container still serves after the change — a silent version swap would not be caught by the host smoke job.
Non-deferrable core
- Both
webapp/ and docker/agents/pi/ in the same PR — fixing one and leaving the other just moves the outage to the next release
- The
nginx -v / start-up verification recorded in the PR body
The v0.75.0 release was blocked by four HIGH CVEs in the webapp image. The cause is structural, not a stale pin.
The defect
webapp/DockerfilepinsFROM nginx:stable-alpine@sha256:97d490c…and runsapk add --no-cache bash sed grep curlwith noapk upgrade. Alpine shippedopenssl 3.5.8-r0andexpat 2.8.4-r0; neither can reach the image by any path that exists in this repository:nginx:stable-alpinestill resolves to that exact digest today.So OS packages in every digest-pinned image here are unpatchable by construction. Verified: that digest carries 4 HIGH; adding
apk upgrade --no-cachetakes it to 0.Scope
webapp/Dockerfile—apk upgrade --no-cacheahead of the existingapk add.docker/agents/pi/Dockerfile— the identical latent failure: digest-pinnednode:*-slim,apt-get install, no upgrade. It would block the release after this one. Fix it in the same change.docker/postgres/Dockerfile— the tag floats, so it picks up docker-library rebuilds. Lower priority; add for consistency.security/release-images.jsonalready tracks a newer nginx-alpine digest (sha256:db35bfc6…) thanwebapp/Dockerfilepins. Scan it — if clean, repoint the base as well.There is no reproducibility trade-off
apk addis already unversioned against the live index, so build reproducibility does not exist to lose. OpenSSF Scorecard's pinned-dependencies check has a closed enum of eight dependency types containing no package manager, soapk upgradecarries no penalty. Docker deleted the anti-upgrade guidance in 2021; hadolint removed DL3005 in 2023.Verification
The nginx official image installs nginx from
nginx.orgvia a one-shotapk add -X <url>repository that is not persisted, soapk upgradedraws from Alpine main/community only. Confirmnginx -vis unchanged and the container still serves after the change — a silent version swap would not be caught by the host smoke job.Non-deferrable core
webapp/anddocker/agents/pi/in the same PR — fixing one and leaving the other just moves the outage to the next releasenginx -v/ start-up verification recorded in the PR body