Skip to content

Update docker CI to run arm64 build on a dedicated runner - #21

Merged
IamCoder18 merged 2 commits into
mainfrom
IamCoder18/update-docker-ci-to-run-arm64-build-on-a-dedicat
Sep 13, 2026
Merged

IamCoder18 merged 2 commits into
mainfrom
IamCoder18/update-docker-ci-to-run-arm64-build-on-a-dedicat

Conversation

@IamCoder18

Copy link
Copy Markdown
Owner

Fixes #20

What

The Docker image workflow no longer builds linux/arm64 under QEMU on an amd64 runner. Each platform now builds natively on its own runner and the results are combined into one multi-arch image:

  • build-amd64 (ubuntu-latest) and build-arm64 (GitHub's free ubuntu-24.04-arm runner) each build the synapse-website bake target for their platform and push the manifest to GHCR by digest (push-by-digest, bare repo name as the exporter name).
  • merge runs docker buildx imagetools create with both digests and attaches all the computed tags (main/v* semver/latest/sha) to the resulting multi-arch manifest list.
  • PR builds are split the same way (build-pr-amd64 / build-pr-arm64 on the synapse-website-pr target) so PR checks also drop QEMU.

website/docker-bake.hcl is unchanged functionally — it still declares both platforms for single-node local builds; CI just overrides platform per runner via --set.

Why

The QEMU-emulated arm64 build dominated the workflow (~3 minutes total). Native per-runner builds should drop it to well under a minute (#20).

How

  • Follows the Docker-documented pattern for splitting multi-arch builds across native runners: per-platform digest pushes + imagetools create merge.
  • The metadata-action step in the build jobs now exists only for its OCI labels (baked into each pushed manifest); its tags are overridden with the bare repo name because push-by-digest rejects tagged refs (verified — buildx errors with can't push tagged ref ... by digest otherwise). Tags are applied once, atomically, by the merge job.
  • Digests travel between jobs as job outputs (parsed from bake's auto-captured metadata output), so no artifacts are needed.
  • No new third-party actions; everything stays SHA-pinned, permissions stay least-privilege, and zizmor reports no findings for the workflow.

Test

  • Replicated the exact CI flow locally against a scratch registry: per-platform native builds with push-by-digest (labels applied, metadata captured), then imagetools create merged both digests — imagetools inspect shows a correct OCI index with linux/amd64, linux/arm64, and provenance attestations.
  • Verified push-by-digest requires clearing metadata tags and that --set "*.tags=<name>" wins over the metadata bake file.
  • actionlint and zizmor pass clean on the workflow; bake --print confirms the resolved per-platform target config.

Checklist

  • CI-only change — no library code touched, ./gradlew test unaffected
  • No new runtime dependencies
  • CHANGELOG.md — not user-facing (follows at next release)

Each platform now builds on its own runner (ubuntu-latest for amd64,
ubuntu-24.04-arm for arm64) and pushes its manifest to GHCR by digest;
a merge job combines the two into a single multi-arch manifest list
with the computed tags. This replaces the QEMU-emulated arm64 build,
which dominated the workflow's ~3 minute runtime.
@coderabbitai

coderabbitai Bot commented Sep 13, 2026 •

Copy link
Copy Markdown

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 613e19e9-23c0-46db-8e52-b6f2d470db0e

📥 Commits

Reviewing files that changed from the base of the PR and between ab776a3 and 09313aa.

📒 Files selected for processing (3)
  • .github/workflows/docker-pr.yml
  • .github/workflows/docker.yml
  • website/docker-bake.hcl

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.

📜 Recent review details
⏰ Context from checks skipped due to timeout. (1)
  • GitHub Check: Kilo Code Review
🔇 Additional comments (3)
.github/workflows/docker-pr.yml (1)

1-67: LGTM!

.github/workflows/docker.yml (1)

3-3: LGTM!

Also applies to: 15-16, 33-39, 41-42, 47-48, 70-71, 78-80, 82-83, 86-96, 98-112, 115-117, 127-148, 153-223

website/docker-bake.hcl (1)

1-2: LGTM!

Also applies to: 6-10


📝 Walkthrough

Walkthrough

Changes

Docker CI workflows

Layer / File(s) Summary
Pull request validation
.github/workflows/docker-pr.yml
Adds native amd64 and arm64 validation builds for pull requests. The builds do not log in to a registry or push images.
Native release builds
.github/workflows/docker.yml
Runs amd64 and arm64 builds on native runners and pushes each image by digest. The workflow no longer runs on pull request events.
Manifest publication and build documentation
.github/workflows/docker.yml, website/docker-bake.hcl
Adds a merge job that creates and inspects a multi-architecture manifest. Updates the bake comments to describe the new CI flow.

Priority: ➖ Normal

Estimated code review effort: 4 (Complex) | ~45 minutes

Change: Refactor · Severity of issue fixed: Medium

Sequence Diagram(s)

sequenceDiagram
  participant GitHubActions
  participant NativeRunners
  participant GHCR
  participant MergeJob
  GitHubActions->>NativeRunners: Build amd64 and arm64 images
  NativeRunners->>GHCR: Push images by digest
  NativeRunners-->>MergeJob: Provide image digests
  MergeJob->>GHCR: Create multi-architecture manifest
  MergeJob->>GHCR: Inspect merged image
Loading

Merge Risk: ⚪ Minimal · up to 09313

The workflow preserves pull-request image validation and publishes release manifests from both native platform images with no confirmed merge-blocking issue.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: Docker CI now runs the arm64 build on a dedicated runner.
Description check ✅ Passed The description directly explains the native amd64 and arm64 builds, digest-based pushes, manifest merging, PR validation, and related testing.
Linked Issues check ✅ Passed The changes satisfy issue #20. .github/workflows/docker.yml runs build-arm64 on ubuntu-24.04-arm and sets linux/arm64, so the arm64 build does not use QEMU on an amd64 runner. The amd64 build …
Out of Scope Changes check ✅ Passed The changes remain within issue #20 scope. The separate PR validation workflow, digest-based publishing, manifest merge, permissions, concurrency, and documentation support native per-platform Docker …
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0…
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch IamCoder18/update-docker-ci-to-run-arm64-build-on-a-dedicat

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.

Comment thread .github/workflows/docker.yml Outdated
IMAGE: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
VERSION: ${{ steps.meta.outputs.version }}
run: |
docker buildx imagetools inspect "$IMAGE:$VERSION"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

WARNING: steps.meta.outputs.version is empty on plain branch pushes (no semver tag), so this inspect runs against an empty tag and fails the merge job.

docker/metadata-action's version output is only set when a semver pattern matches — i.e. on v* tag pushes. On a regular push to main (the workflow's other push: trigger), version is empty, so the command becomes effectively docker buildx imagetools inspect "ghcr.io/IamCoder18/synapse-website:", which fails. Fall back to a tag that is always present for the configured triggers (e.g. latest, which is enabled for the default branch and present on every push: branches: [main] run):

Suggested change
docker buildx imagetools inspect "$IMAGE:$VERSION"
docker buildx imagetools inspect "${IMAGE}:${VERSION:-latest}"

Reply with @kilocode-bot fix it to have Kilo Code address this issue.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

False positive — the version output is not empty on branch pushes. docker/metadata-action sets version from the first matching tag rule, and type=ref,event=branch always matches on the push: branches: [main] trigger. Verified against the real run on main (run 34765339776), where the extract-metadata step logs:

org.opencontainers.image.version=main

So on a main push this inspects ghcr.io/iamcoder18/synapse-website:main (which the merge job just pushed), and on a v* tag push version is the semver. It can only be empty if none of the tag rules matched, which cannot happen for this workflow's triggers (type=ref,event=branch covers main, type=semver covers tags, type=raw,value=latest is unconditional on the default branch).

Still, since an empty version would silently inspect the wrong ref, the step now fails loudly in that case instead:

docker buildx imagetools inspect "${IMAGE}:${VERSION:?metadata-action produced no version tag}"

@kilo-code-bot

kilo-code-bot Bot commented Sep 13, 2026 •

Copy link
Copy Markdown

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Files Reviewed (3 files)
  • .github/workflows/docker.yml
  • .github/workflows/docker-pr.yml
  • website/docker-bake.hcl
Previous Review Summary (commit 3415b85)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit 3415b85)

Status: 1 Issue Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 1
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
.github/workflows/docker.yml 225 Inspect image step fails on branch pushes because steps.meta.outputs.version is empty when no semver tag is present
Files Reviewed (2 files)
  • .github/workflows/docker.yml - 1 issue
  • website/docker-bake.hcl - 0 issues

Fix these issues in Kilo Cloud


Reviewed by minimax-m3 · Input: 0 · Output: 0 · Cached: 0

Push/tag publishing (build + digest push + manifest merge) stays in
docker.yml; PR validation builds move to docker-pr.yml. Each file only
triggers for its own event, so check lists no longer contain skipped
jobs.
@IamCoder18
IamCoder18 merged commit 367bb03 into main Sep 13, 2026
5 checks passed
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.

Update docker CI to run arm64 build on a dedicated runner to reduce build times

1 participant