Skip to content

feat(image): publish linux/amd64 and linux/arm64 - #6

Merged
Aleksei Sviridkin (lexfrei) merged 2 commits into
mainfrom
feat/multi-arch-image
Sep 28, 2026
Merged

Aleksei Sviridkin (lexfrei) merged 2 commits into
mainfrom
feat/multi-arch-image

Conversation

@lexfrei

Copy link
Copy Markdown
Contributor

What

The proxy image can't run on arm64 nodes today. The Dockerfile hardcodes GOARCH=amd64, so ghcr.io/cozystack/keycloak-kms-proxy is published for amd64 only. With this change the release publishes it as a linux/amd64 + linux/arm64 index.

Why cross-compiling instead of QEMU

cgo has to stay on, because pg_query_go compiles the libpg_query C parser into the binary. The build stage now runs on $BUILDPLATFORM. When the target differs from the host, it installs Debian's cross gcc (gcc-aarch64-linux-gnu or gcc-x86-64-linux-gnu) and sets CC for the target. So the C parser is never compiled under emulation, and the release stays one buildx call on one runner, with no setup-qemu-action. The cross toolchain links against bookworm's glibc, the same version distroless/base-debian12 ships, so the runtime base does not change.

CI

CI gets an image job that builds both platforms without pushing. A change that breaks the arm64 cross-build fails there, not on tag push. A separate commit pins every action in both workflows to a full commit SHA with a version comment. The release job holds packages: write, so a moved tag could overwrite the published image.

Testing

  • On an arm64 host, a two-platform buildx build gives x86-64 and AArch64 ELF binaries linked against the glibc loader (checked with file).
  • The arm64 image runs natively with --version, and the amd64 image does the same under emulation.
  • I reproduced the CI path, amd64 host to arm64 target, in an amd64 golang:1.26.2-bookworm container with gcc-aarch64-linux-gnu. It builds an AArch64 binary.
  • go vet ./..., go test -race ./..., golangci-lint run (0 issues) and actionlint are clean.

Floating major tags can be moved to arbitrary code by whoever controls
the action repository. The release job holds packages:write and
contents:write, so a retargeted tag would run with the rights to
overwrite the published image. Pin each action to the commit of the
latest release in the major already in use.

Assisted-by: LLM
Signed-off-by: Aleksei Sviridkin <f@lex.la>
The image was amd64-only because the Dockerfile hardcoded GOARCH=amd64,
so arm64 nodes could not run the proxy at all.

cgo stays on: pg_query_go compiles the libpg_query C parser into the
binary. The build stage now runs on the build host and cross-compiles
with Debian's cross gcc for the target arch instead of building under
QEMU, which would compile the whole C parser emulated. The cross
toolchain links against bookworm's glibc, the same one the
distroless/base-debian12 runtime ships.

Release publishes both platforms as one index. CI builds the image for
both platforms without pushing, so a change that breaks the arm64
cross-build fails on the pull request instead of at release time.

Assisted-by: LLM
Signed-off-by: Aleksei Sviridkin <f@lex.la>
@coderabbitai

coderabbitai Bot commented Sep 27, 2026 •

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: fdb50593-28b7-4628-858d-7a06a3c05ee0


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@IvanHunters IvanHunters left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed statically in a hermetic clone. Verified both stage base images are multi-arch via crane, confirmed every Debian cross-toolchain package exists in bookworm, and checked all 7 GitHub Actions SHA pins match their tags. The real CI run on this head executed the production cross-compile path (amd64 runner, CC=aarch64-linux-gnu-gcc, CGO on) and succeeded. LGTM. Two minor non-blocking notes.

@lexfrei
Aleksei Sviridkin (lexfrei) merged commit e7f3031 into main Sep 28, 2026
5 checks passed
@lexfrei
Aleksei Sviridkin (lexfrei) deleted the feat/multi-arch-image branch September 28, 2026 17:28
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.

2 participants