GitLab CI/CD Multi-Arch Container Image Build Prompt
Design a GitLab CI/CD pipeline that builds, tags, and pushes multi-architecture (amd64 + arm64) container images with buildx, QEMU, registry-backed cache, and a single manifest list.
- Target user
- Platform engineers shipping images for mixed amd64/arm64 fleets
- Difficulty
- Advanced
- Tools
- Claude, ChatGPT
The prompt
You are a build engineer who has shipped multi-architecture container images for Graviton and Apple-silicon developers without doubling pipeline time or maintaining two parallel jobs. I will provide: - Current single-arch `.gitlab-ci.yml` build job and Dockerfile - Target architectures and where images run (cluster node arch, dev laptops) - Runner inventory (native arm runners available? amd64 only?) - Registry (GitLab Container Registry vs external) and current cache strategy - Build time and image size pain points Your job: 1. **Decide the build topology** — compare three approaches: (a) single buildx job with QEMU emulation, (b) fan-out matrix of native-arch jobs + a separate `manifest create` job, (c) hybrid native arm runner + emulated fallback. Recommend one for my runner inventory and justify the tradeoff in wall-clock time vs complexity. 2. **buildx setup** — show the exact `before_script` to register QEMU (`tonistiigi/binfmt`), create and bootstrap a builder instance, and log into the registry. Note which steps need `services: docker:dind` vs a rootless or Kubernetes executor. 3. **The build job** — write `docker buildx build --platform linux/amd64,linux/arm64 --push` with: registry-backed cache (`--cache-to type=registry,mode=max` / `--cache-from`), provenance + SBOM attestation flags, and OCI annotations. Explain `mode=max` cache cost vs hit rate. 4. **Tagging strategy** — produce the manifest-list tag plus immutable per-commit tags. Show the CI variable expressions (`$CI_COMMIT_SHORT_SHA`, `$CI_COMMIT_TAG`, default-branch `latest`) and how to keep arch-specific tags out of users' way. 5. **Native fan-out variant** — if I have arm runners, give the `parallel:matrix` over `ARCH` with runner `tags:`, then a final job that runs `docker buildx imagetools create` to assemble the manifest from the per-arch digests. 6. **Verification** — commands to assert the manifest lists both platforms (`docker buildx imagetools inspect`) and a CI gate that fails if either arch is missing. 7. **Cost & speed** — quantify emulation overhead, recommend caching layers that are arch-independent, and flag when arm emulation is too slow to be worth it. Output as: (a) full `.gitlab-ci.yml` build stage, (b) the manifest-assembly job, (c) verification snippet, (d) a decision note on emulation vs native for my setup.