The image never takes Debian's updates: the layer that upgrades is served from the builder's cache #300
Labels
No labels
accessibility
authentication
breaking change
bug
documentation
enhancement
interface
internationalisation
observability
performance
security
tier
1
tier
2
tier
3
tier/4
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
Postulo/postulo#300
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The dev image for
420b9d102failed its scan gate (run 585): Grype found OpenSSL3.0.20-1~deb12u2in the image with3.0.22-1~deb12u1available, three CVEs at High andone at Critical. Nothing in that push touched the image. The fix had been in Debian's
security archive for days, and the image did not have it because the layer that takes
Debian's updates never ran.
What the logs say
docker/Dockerfileinstalls the runtime's packages in one layer,apt-get update && apt-get upgrade -y && apt-get install …, and #155 put the upgradethere on purpose: the base image keeps what it was built with, so the upgrade is the only
thing that reaches a package like
libssl3, which arrives with Python.A layer is served from the builder's cache for as long as its text and the layer under it
are the same. Neither changes when Debian publishes an update. On the runner:
e143fc80d, 25 Septemberdefault, the one that is scannedCACHEDpostulo-dev, the one that is pushed, amd64CACHEDpostulo-dev, arm64CACHED420b9d102, 28 SeptemberdefaultCACHEDRun 582's full report already listed
libssl3 3.0.20-1~deb12u2, fixed in3.0.22-1~deb12u1, at Medium, which is under the gate. Between the two runs the findingswere rescored, and the gate did its job.
So the sentence in the Dockerfile, "between an image that drifts towards being patched and
one that reliably stays unpatched, this takes the first", has not been true on any builder
that keeps its cache. The image stays at the day its apt layer was last built, and the
published dev images, both architectures, have been carrying packages with a fix
available.
Two builders are involved, each with a cache of its own: the daemon's, whose image is
scanned, and the
docker-containerbuilder buildx pushes from. A fix that refreshes oneof them leaves a scanned image and a published image that differ.
What to do
of that layer's cache key. A new value makes the layer run again, on whichever builder.
image that is scanned and the image that is published asked Debian the same question.
--pullbeside it, so the base image is asked for as well whatever the builder'sdefault is.
scripts/scan-image.shdoes the same when it builds the image itself.build log.
Not
--no-cache: it would rebuild the stylesheet and the Python environment on every push,under emulation for arm64, to refresh one layer. Not a date as the value: an update
published after the day's first build would fail the gate until midnight, which is a gate
failing for a reason nobody can act on.
Done when
when Debian was asked.
tests/test_image_build.pyholds the argument above the layer and holds every build inthe workflows and the scan script to passing it.
image.
Landed as
05781f881, and run 587 is the first one built with it. What its log shows:default, the image that is scanned3.0.20-1~deb12u2to3.0.22-1~deb12u1postulo-dev, the image that is pushedpostulo-devAll three printed
Debian's packages as of: 2026-09-29T06:39:57Z, the one moment the runread from the clock. The gate's verdict was "Nothing fixable at HIGH,CRITICAL or above",
and the image was published as
0.3.0-dev.05781f8. The whole job took eleven minutes,against twelve for run 582, so running the layer costs less than the variation between
runs.
The seven other jobs on that commit are green as well.
Two things the logs showed that the issue did not know when it was filed:
that was scanned. It never did: the two builders share nothing. The comments are
corrected, and the two builds are tied together by the moment they are given.
so its packages were the ones of its day. Its scan read the daemon's cached layer, which
was not the image that was pushed. A release built from now on is scanned and pushed from
the same moment.