Skip to content

chore(docker): bump alpine 3.21 to 3.24 in the backup-tools and runtime stages (agent-os-bmo) - #51

Merged
thinkbig1979 merged 1 commit into
mainfrom
chore/alpine-3.24
Aug 2, 2026
Merged

chore(docker): bump alpine 3.21 to 3.24 in the backup-tools and runtime stages (agent-os-bmo)#51
thinkbig1979 merged 1 commit into
mainfrom
chore/alpine-3.24

Conversation

@thinkbig1979

Copy link
Copy Markdown
Owner

Takes the alpine half of Dependabot #13. The Go 1.25.12 → 1.26.5 builder bump is deliberately excluded — see below.

Changes

Two lines in docker/Dockerfile: alpine:3.21alpine:3.24 at :67 (backup-tools stage) and :124 (runtime stage). Nothing else.

Why alpine is taken but drilled

agent-os-o9l's Trivy baseline established alpine 3.21.7 contributes zero findings — the fixable HIGH/CRITICAL surface was all in restic and rclone, cleared by agent-os-9e1. So there is no security pressure here; it is patch-grade hygiene on a trusted base.

But three releases in one step changes the package set underneath restic, rclone, the docker CLI plugins and the entrypoint's su-exec/shadow usage. What actually moved:

3.21 3.24
docker-cli 27.3.1-r5 29.5.3-r0
docker-cli-buildx 0.19.1-r5 0.34.1-r0
docker-cli-compose 2.31.0-r5 5.1.4-r0
su-exec 0.2-r3 0.3-r0
shadow 4.16.0-r1 4.18.0-r1
restic / rclone 0.19.1 / 1.74.4 unchanged (static, pinned via ARG)

restic and rclone are pinned static binaries downloaded independently of the base, so the backup engine itself does not move. All the risk is in the apk-provided tooling — and compose jumped three majors.

Two drills

Backup/restore. Repo init → run → snapshot listed with capstan tags → preview → destroy the stack dir → restore → sha256 byte-for-byte identical pre/post → restic check --read-data reports "no errors were found". A deliberately-wrong data.txt was planted before the restore and came back with the correct original content, proving the restore actually wrote rather than leaving already-correct files alone.

Compose lifecycle, because the first drill touches no compose code at all and would have passed identically if every stack operation were broken. Start → status → pull → stop through the API, each cross-checked against docker ps independently rather than trusting the API's own report.

The load-bearing result: parseComposePSOutput (docker_lifecycle.go:491-533) unmarshals docker compose ps --format json into an anonymous struct reading ID, Name, Service, State, Health, Image, Ports. All seven are present and correctly cased in compose v5.1.4's output. This matters because that function silently continues on unmarshal error — a changed JSON schema would not fail loudly, it would yield zero containers and report a running stack as stopped. Verified it does not.

Also confirmed under the new base: entrypoint socket-GID discovery still builds the dockerhost group (GID 130, appuser joined), PID 1 still runs as uid 1000, wget still serves the healthcheck (docker inspect reports healthy), and docker / docker compose / docker buildx all execute in-container.

Why the Go bump is excluded

backend/go.mod carries both go 1.25.0 and toolchain go1.25.12, and agent-os-vkr established that go.mod's toolchain and the Dockerfile's builder must move together. With GOTOOLCHAIN=auto, a 1.26.5 builder reading toolchain go1.25.12 downloads and re-execs into 1.25.12 anyway — so the bump would add a toolchain download to every image build, over the network, for no change in the shipped binary, while putting the two pins out of step. Moving to Go 1.26 is a real decision that must change both files in one reviewed change, and a Go minor can shift vet/lint behaviour, which would land on top of golangci-lint arriving via agent-os-far.

Switching the runtime base to debian-slim was considered and rejected: the usual musl arguments do not apply (CGO_ENABLED=0 at docker/Dockerfile:59 against pure-Go modernc.org/sqlite, so no libc is linked), while the costs are concrete — no default-repo docker-cli/buildx/compose, no su-exec, differing addgroup/adduser flags, no wget.

Closes agent-os-bmo.

🤖 Generated with Claude Code

…tages (agent-os-bmo)

Patch-grade hygiene bump on a trusted base: agent-os-o9l's Trivy baseline
found zero findings from alpine 3.21.7 itself, so there is no security
pressure behind this change. Three releases in one step still changes
the package set underneath restic, rclone, the docker CLI plugins, and
the entrypoint's su-exec/shadow usage, so it is validated with a full
backup/restore drill against the rebuilt image rather than a CI glance
alone.

Drill (API-driven, AUTH_DISABLED=true, docker.sock mounted,
--network host): repo init -> backup run (WS-triggered) -> snapshot
listed with capstan tags -> preview lists expected paths -> stack dir
destroyed and seeded with a wrong placeholder file -> restore run
(WS-triggered) -> sha256 over the 3 original files identical
pre/post-restore, and the deliberately-wrong data.txt was overwritten
with the correct original content, proving restore actually wrote
rather than no-oping -> restic check --read-data reports "no errors
were found". Also verified: entrypoint.sh's docker.sock GID discovery
(dockerhost group created at GID 130, appuser joined), server runs as
non-root appuser (uid=1000), and docker/compose/buildx/wget all execute
inside the container (docker-cli 27.3.1->29.5.3, buildx 0.19.1->0.34.1,
compose 2.31.0->5.1.4 majors; su-exec 0.2->0.3, shadow 4.16.0->4.18.0
patch bumps; restic 0.19.1 and rclone 1.74.4 unchanged since they are
pinned static binaries fetched independently of the alpine base).

Deliberately excludes the golang:1.25.12-alpine builder image and
backend/go.mod. Those two must move together: go.mod pins
"toolchain go1.25.12", and with GOTOOLCHAIN=auto a newer builder image
just downloads and re-execs into that pinned toolchain on every build,
so bumping the Dockerfile's Go image alone adds a network toolchain
fetch to every build for no change in the shipped binary, while putting
the two pins out of step. Moving to Go 1.26 is a real decision that
must change both files together in one reviewed change, and is
deferred to a separate PR.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@thinkbig1979
thinkbig1979 merged commit 8a1f960 into main Aug 2, 2026
10 of 11 checks passed
@thinkbig1979
thinkbig1979 deleted the chore/alpine-3.24 branch August 2, 2026 22:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant