Fix GLIBC mismatch, and make the release prove the container boots - #29
Merged
Merged
Conversation
The image built and published fine, then died on start: utopia-server: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.38' not found rust:1-slim follows upstream and is on trixie now (glibc 2.41); the runtime stage is bookworm (2.36). Nothing in a successful build reveals that. Pinning the build stage to rust:1-slim-bookworm ties both ends to one distro and keeps a future upstream bump from silently reopening the gap. The workflow now loads the image, runs it against Postgres, and only publishes after the container serves /api/v1/health and registers a user — migrations, argon2 and JWT issuance all exercised for real. Health is checked at its nested path with a body assertion: the image serves an SPA fallback, so /health returns 200 with index.html and would have passed while proving nothing.
WaylandYang
added a commit
that referenced
this pull request
Aug 28, 2026
The image built and published fine, then died on start: utopia-server: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.38' not found rust:1-slim follows upstream and is on trixie now (glibc 2.41); the runtime stage is bookworm (2.36). Nothing in a successful build reveals that. Pinning the build stage to rust:1-slim-bookworm ties both ends to one distro and keeps a future upstream bump from silently reopening the gap. The workflow now loads the image, runs it against Postgres, and only publishes after the container serves /api/v1/health and registers a user — migrations, argon2 and JWT issuance all exercised for real. Health is checked at its nested path with a body assertion: the image serves an SPA fallback, so /health returns 200 with index.html and would have passed while proving nothing.
This was referenced Sep 14, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The failure
The published image pulled and started, then exited immediately:
rust:1-slimtracks upstream and is on trixie now (glibc 2.41). The runtime stage isdebian:bookworm-slim(glibc 2.36). The binary linked against a newer libc than the image it ships in.Pinning the build stage to
rust:1-slim-bookwormties both ends to one distro, and keeps a future upstream bump from silently reopening the same gap.Why CI could not have caught it
It builds clean. Publishing succeeded. Every signal was green — the image simply cannot start. The gap between "builds" and "runs" had nothing covering it.
So the release now loads the image and runs it against a real Postgres before publishing, asserting:
/api/v1/healthreturns{"status":"ok"}— process alive, migrations appliedPOST /api/v1/auth/registerreturns 200 with a token — argon2 hashing and JWT issuance work end to end (the path that would have caught therust_cryptopanic in Fix auth-bypass advisory in jsonwebtoken (CVE-2026-25537) #23)Only then does it push.
Health is checked at the nested path with a body assertion on purpose: the image serves an SPA fallback, so a request to
/healthreturns 200 withindex.html. Checking that would have passed while proving nothing.Polling conditions are written as
if, notcmd && break— underset -ethe latter aborts the run the first time a service is not ready yet.