Move the Go buildpack to a glibc/bookworm base (align with other stacks, unblock cgo)
Context
Go is the only language stack still building on alpine/musl. Every other stack is already debian/glibc:
| stack | BaseDistro() |
build image |
|---|---|---|
| Go | alpine | golang:<v>-alpine |
| Python | debian | python:<v>-slim |
| Ruby | debian | ruby:<v>-slim |
| Node | debian | node:<v>-slim |
| Bun | debian | (debian) |
| Rust | debian | (debian) |
So this isn't a scary platform-wide migration to glibc, it's removing Go's one-off inconsistency. The team already accepted glibc's tradeoffs for every other language.
Why
musl is where a class of compatibility problems live, and glibc is the lingua franca of the prebuilt-binary world (manylinux Python wheels, Node prebuilt native addons, prebuilt CLIs/ML runtimes, vendored static libs). Miren already banked most of that win by putting Python/Ruby/Node on debian. The remaining musl tax is paid only by Go, and cgo is the most visible symptom:
- Source-compiled cgo (e.g.
mattn/go-sqlite3) fails today because the builder has no C toolchain and effectivelyCGO_ENABLED=0. - Prebuilt-glibc cgo (e.g.
github.com/duckdb/duckdb-go/v2, which vendors a glibc static archive) can't link against musl at all — this is thekoikonom/jobsv2case that kicked this off. Error:build constraints exclude all Go files in …/duckdb-go-bindings/lib/linux-amd64.
Moving Go to bookworm makes both just work, with no app.toml flag and no cgo-detection machinery.
Proposal
Build the Go stack on golang:<v>-bookworm (publish to oci.miren.cloud), with a C toolchain available, so cgo works when the code needs it. Switch GoStack.BaseDistro() to "debian" so the existing apt-vs-apk augmentation machinery applies.
Protect the tiny-image superpower: keep the final runtime stage adaptive. Pure-Go (cgo off) should still emit a static binary on distroless/scratch, exactly as small as today; only actual cgo apps land on debian-slim at runtime. Do NOT regress image size for the 99% pure-Go case by naively running everything on full debian.
Scope / risks
- Publish + maintain
golang:<v>-bookwormimages. - Flip
GoStack.BaseDistro()and adjustpkg/stackbuild/golang.go(toolchain present; adaptive final stage; ensure static binaries still produced for cgo-off). - Test: rebuild the Go
testdata/apps + blackbox suite, confirm static-binary output for pure-Go, eyeball image-size deltas. - Slightly heavier build/cache image.
No new long-lived surface area to maintain — the appeal is that it deletes an inconsistency rather than adding a feature.
Current workaround
A hand-written Dockerfile.miren on a golang:1.x-bookworm base with CGO_ENABLED=1 builds and runs duckdb cleanly (verified locally during the jobsv2 debugging session). That stays the escape hatch until/unless this lands.
Note
Touches "what's our buildpack base philosophy," so this may warrant an RFD before implementation. Filing as an issue first to decide RFD-vs-build from here.