Builds code.aneur.in/zampler/zampler:latest as an amd64 + arm64 manifest list so it can run on the Pi and on common x86 machines from the same tag.
Approach
Zampler is pure Go with cgo disabled (modernc.org/sqlite), so both arches cross-compile from the amd64 runner at native speed with no emulation. The runtime Dockerfile has no RUN steps, so buildx assembles the arm64 image on the amd64 host without QEMU too. The arm64 runner is intentionally not used — see #3 for why, and the pros/cons of revisiting that.
Changes
build.yml: Build binary → cross-compile dist/zampler-linux-{amd64,arm64}; new buildx setup step (docker-container driver); promote :latest→:previous via buildx imagetools create (copies the manifest list registry-side instead of pull/tag/push); final step is one docker buildx build --platform linux/amd64,linux/arm64 --push. Added docker-cli-buildx to apk add.
.dockerignore / .gitignore: track the new dist/ layout.
Verified locally
Cross-compile of both arches (correct static ELF, pure-Go confirmed); Dockerfile + .dockerignore + TARGETARCH interpolation; buildx accepting the two-platform matrix. Not verifiable locally (Docker Hub rate limit): the real --push manifest-list publish, and that the runner permits the docker-container buildx driver — watch the first main build.
Builds `code.aneur.in/zampler/zampler:latest` as an amd64 + arm64 manifest list so it can run on the Pi and on common x86 machines from the same tag.
## Approach
Zampler is pure Go with cgo disabled (`modernc.org/sqlite`), so both arches cross-compile from the amd64 runner at native speed with no emulation. The runtime Dockerfile has no `RUN` steps, so `buildx` assembles the arm64 image on the amd64 host without QEMU too. The `arm64` runner is intentionally not used — see #3 for why, and the pros/cons of revisiting that.
## Changes
- **build.yml**: `Build binary` → cross-compile `dist/zampler-linux-{amd64,arm64}`; new buildx setup step (`docker-container` driver); promote `:latest`→`:previous` via `buildx imagetools create` (copies the manifest list registry-side instead of pull/tag/push); final step is one `docker buildx build --platform linux/amd64,linux/arm64 --push`. Added `docker-cli-buildx` to `apk add`.
- **Dockerfile**: `ARG TARGETARCH` + `COPY dist/zampler-linux-${TARGETARCH}`.
- **.dockerignore / .gitignore**: track the new `dist/` layout.
## Verified locally
Cross-compile of both arches (correct static ELF, pure-Go confirmed); Dockerfile + `.dockerignore` + `TARGETARCH` interpolation; buildx accepting the two-platform matrix. Not verifiable locally (Docker Hub rate limit): the real `--push` manifest-list publish, and that the runner permits the `docker-container` buildx driver — watch the first `main` build.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Zampler is pure Go with CGO disabled (modernc.org/sqlite), so both
architectures cross-compile from the amd64 runner at native speed with
no emulation. The runtime Dockerfile has no RUN steps, so buildx can
assemble the arm64 image on the amd64 host without QEMU too.
- Cross-compile dist/zampler-linux-{amd64,arm64} in one job.
- Dockerfile copies dist/zampler-linux-${TARGETARCH}; buildx sets
TARGETARCH per platform leg.
- Replace `docker build`/`push` with a single `docker buildx build
--platform linux/amd64,linux/arm64 --push`, producing a manifest list
at :latest.
- Promote :latest to :previous with `buildx imagetools create`, which
copies the manifest list registry-side instead of pulling a single
arch and re-pushing.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
aneurin
merged commit 7f57e25dcf into main2026-09-07 00:42:59 +00:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Builds
code.aneur.in/zampler/zampler:latestas an amd64 + arm64 manifest list so it can run on the Pi and on common x86 machines from the same tag.Approach
Zampler is pure Go with cgo disabled (
modernc.org/sqlite), so both arches cross-compile from the amd64 runner at native speed with no emulation. The runtime Dockerfile has noRUNsteps, sobuildxassembles the arm64 image on the amd64 host without QEMU too. Thearm64runner is intentionally not used — see #3 for why, and the pros/cons of revisiting that.Changes
Build binary→ cross-compiledist/zampler-linux-{amd64,arm64}; new buildx setup step (docker-containerdriver); promote:latest→:previousviabuildx imagetools create(copies the manifest list registry-side instead of pull/tag/push); final step is onedocker buildx build --platform linux/amd64,linux/arm64 --push. Addeddocker-cli-buildxtoapk add.ARG TARGETARCH+COPY dist/zampler-linux-${TARGETARCH}.dist/layout.Verified locally
Cross-compile of both arches (correct static ELF, pure-Go confirmed); Dockerfile +
.dockerignore+TARGETARCHinterpolation; buildx accepting the two-platform matrix. Not verifiable locally (Docker Hub rate limit): the real--pushmanifest-list publish, and that the runner permits thedocker-containerbuildx driver — watch the firstmainbuild.🤖 Generated with Claude Code
Zampler is pure Go with CGO disabled (modernc.org/sqlite), so both architectures cross-compile from the amd64 runner at native speed with no emulation. The runtime Dockerfile has no RUN steps, so buildx can assemble the arm64 image on the amd64 host without QEMU too. - Cross-compile dist/zampler-linux-{amd64,arm64} in one job. - Dockerfile copies dist/zampler-linux-${TARGETARCH}; buildx sets TARGETARCH per platform leg. - Replace `docker build`/`push` with a single `docker buildx build --platform linux/amd64,linux/arm64 --push`, producing a manifest list at :latest. - Promote :latest to :previous with `buildx imagetools create`, which copies the manifest list registry-side instead of pulling a single arch and re-pushing. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>