feat(build): publish multi-arch container image to GHCR on release - #631
Open
stevapple wants to merge 1 commit into
Open
feat(build): publish multi-arch container image to GHCR on release#631stevapple wants to merge 1 commit into
stevapple wants to merge 1 commit into
Conversation
Add build/Dockerfile and a publish-image job so each tag pushes ghcr.io/modelpack/modctl:<tag> and :latest for linux/amd64 and linux/arm64, letting users run modctl in CI/CD without installing the Go toolchain. The image is built with CGO_ENABLED=0, which selects the pure-Go go-git backend (pkg/source/git_gogit.go) and pure-Go os/user. The released tarball binaries link glibc statically with CGO enabled, so their NSS-backed os/user lookups fail on a distroless base -- user.Current() in config.NewRoot() panics with "unknown userid 65532" before any command runs. This is the same class of failure as modelpack#285. The builder cross-compiles from $BUILDPLATFORM, so the job needs no QEMU and runs independently of the existing binary matrix. Closes modelpack#630 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: YR Chen <stevapple@icloud.com>
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.
Closes #630
Publishes
modctlas a multi-arch container image so it can be used in CI/CD without installing the Go toolchain.Changes
build/Dockerfile— cross-compiling builder (golang:1.25on$BUILDPLATFORM) plus agcr.io/distroless/static-debian13:nonrootruntime, matching the layout used bymodel-csi-driver. The version ldflags mirror the ones in the existing release build, somodctl versionreports the same fields from the image as from the released tarballs..github/workflows/release.yaml— apublish-imagejob that pushesghcr.io/modelpack/modctl:<tag>and:latestforlinux/amd64andlinux/arm64on everyv*tag, usingGITHUB_TOKENwithpackages: write.The job is independent of the existing binary matrix, and because the builder cross-compiles it needs no QEMU — the whole job takes about as long as a single
go build.Why
CGO_ENABLED=0The released Linux tarball binaries are built with
CGO_ENABLED=1and a statically linked glibc, which breaks NSS-backedos/userlookups. Dropping such a binary into a distroless base panics before any command runs:config.NewRoot()callsuser.Current()to derive the default storage and log directories, and panics if it fails. This is the same class of failure as #285 / #433 (getgrgid_rsegfault in the static binaries).Building with
CGO_ENABLED=0avoids it entirely:os/useruses the pure-Go implementation that reads/etc/passwd(where distroless does have an entry for uid 65532), and the build selects the pure-Go go-git backend via the existing//go:build !enable_libgit2constraint inpkg/source/git_gogit.go.Worth flagging for reviewers: this means the image binary uses go-git while the tarball binaries use libgit2.
model-csi-driveralready builds its release binaries withCGO_ENABLED=0, so there is precedent in the org, but if you would rather the image match the tarballs exactly, the alternative is to keep CGO and add theosusergo/netgotags proposed in #433 — happy to switch.Testing
Built locally with
docker buildxfor both platforms:The resulting manifest list carries
linux/amd64andlinux/arm64(42–46 MB per architecture). Both run as the non-root user:End-to-end check against Qwen2.5-0.5B-Instruct mounted into the container:
Notes
docker run ... modctl <args>works butsh -cstyle invocations do not. If you would prefer a shell for CI systems that injectcommands:blocks,ubuntu:24.04(as inmodel-csi-driver) is a drop-in change to the final stage.