fix(docker): revert builder base from rust:alpine to rust:latest - #13
Merged
Merged
Conversation
Every build failure since switching the builder to rust:alpine (in an earlier "lighter/faster pull" change) traces back to one root cause, confirmed via web research: rust-lang/cargo#7563. *-unknown-linux-musl targets default to +crt-static, which is fundamentally incompatible with proc-macro crates (dylib-style loading) on a musl HOST. sqlx-macros needs to run natively during compilation regardless of the cross --target requested for the final binary, and on an Alpine/musl builder that host-native build is broken by this cargo/rustc limitation -- no combination of CC/linker wrapper juggling fixes it, since the problem is the host toolchain itself, not our zig configuration. On a glibc host (rust:latest), the host triple (x86_64-unknown-linux-gnu) never touches musl or our zig wrapper at all -- proc-macros just build natively against glibc, and only the actual --target musl artifacts (compiled via the zig wrapper) end up statically linked. This is what the Dockerfile did for weeks (PRs #1-8) before the alpine switch. Verified locally: full cold-cache build for amd64 completes cleanly (previously failed consistently on alpine), and `file` on the resulting binary confirms "statically linked" -- the shipped artifact is still a fully static musl binary either way, since the builder's own base image has no bearing on the --target-compiled output. Only the throwaway build-time toolchain container changes; nothing about the shipped image does.
vishwateja-angirekula
approved these changes
Jul 9, 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.
Summary
Every build failure since the Alpine builder switch (2h QEMU hang → stale cache ABI mismatch → host/target CC mixup → UBSan symbol relocation) traces back to one root cause, confirmed via web research: rust-lang/cargo#7563.
*-unknown-linux-musltargets default to+crt-static, which is fundamentally incompatible with proc-macro crates (dylib-style loading) on a musl host.sqlx-macrosmust run natively during compilation regardless of the cross--targetrequested for the final binary, and that host-native build is broken by this cargo/rustc limitation on Alpine — no amount of CC/linker wrapper configuration fixes it, since the problem is the host toolchain itself.On a glibc host (
rust:latest), the host triple (x86_64-unknown-linux-gnu) never touches musl or the zig wrapper at all — proc-macros build natively against glibc, and only the actual--targetmusl artifacts (compiled via zig) end up statically linked. This is exactly what the Dockerfile did for weeks (PRs #1-8) before the Alpine switch.Important: this does not affect the shipped artifact. The builder's own base image is a throwaway compile-time container; the final
uc-serverbinary is still cross-compiled via--target x86_64/aarch64-unknown-linux-musland the final stage is stillFROM scratch. Verified locally:fileon the built binary confirmsstatically linked, stripped— still a fully static musl binary, still runs on Alpine or anywhere else with no libc present.Test plan
fileon the resulting binary confirms it's statically linked (no glibc/dynamic dependency leaked into the shipped artifact)