Skip to content

Publish the image for linux/arm64 as well as linux/amd64 - #4

Merged
zhanghaohit merged 2 commits into
mainfrom
feat/multiarch-image
Oct 28, 2026
Merged

zhanghaohit merged 2 commits into
mainfrom
feat/multiarch-image

Conversation

@zhanghaohit

Copy link
Copy Markdown
Collaborator

What

4pdosc/cache_aware_router is published as a multi-arch image (linux/amd64 + linux/arm64) instead of amd64 only.

  • Each architecture builds natively on its own runner: amd64 on ubuntu-latest, arm64 on ubuntu-24.04-arm.
  • On a version tag, each job pushes its image by digest; a merge job then creates a manifest list over both digests and puts the version tag (and latest, except for prereleases) on it. The tag logic is unchanged.
  • Pull requests now run both builds with nothing pushed (no login, no push, no merge job), so an arm64 breakage shows up before a release.
  • Every build is smoke-tested on its own runner: the image architecture matches the target, the binary prints --version, and config.example.yaml passes --config-check.

Why native runners

An arm64 leg under QEMU is what kept this amd64-only: compiling Rust there is very slow. Cross-compiling with cargo was the alternative, but aws-lc-sys (rustls' crypto provider) needs an aarch64 C toolchain and cmake in the builder. Native arm64 runners keep the Dockerfile unchanged and build at native speed.

Testing

The PR run itself is the test: both platform builds and their smoke tests must pass. The push path (digest push + manifest merge) only runs on a tag.

The release built amd64 only, because an arm64 leg of this Rust build
under QEMU was too slow to be worth it. Build each architecture natively
instead: amd64 on ubuntu-latest, arm64 on the ubuntu-24.04-arm runner.
Each job pushes its image by digest and a merge job tags a manifest list
over both, so the version and latest tags stay a single multi-arch image.

Cross-compiling was the other option, but aws-lc-sys (rustls' crypto
provider) needs an aarch64 C toolchain and cmake in the builder; native
runners keep the Dockerfile unchanged.

Pull requests now run both builds with nothing pushed, and every build is
smoke-tested on its own runner: the image architecture matches the
target, the binary prints its version, and config.example.yaml passes
--config-check.
The image's architecture field is only what the image claims. An amd64
binary inside an arm64 image still runs on a runner with binfmt
emulation, so --version alone would not catch it; read the ELF machine
of the binary copied out of the image and require it to match.
@zhanghaohit
zhanghaohit merged commit 8498715 into main Oct 28, 2026
6 checks passed
@zhanghaohit zhanghaohit mentioned this pull request Oct 28, 2026
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.

1 participant