Skip to content

Build the coordinator image with Jib for every Linux platform the base image publishes - #49

Merged
velo merged 2 commits into
mainfrom
multi-arch-image-via-jib
Sep 24, 2026
Merged

velo merged 2 commits into
mainfrom
multi-arch-image-via-jib

Conversation

@velo

@velo velo commented Sep 24, 2026 •

Copy link
Copy Markdown
Owner

The published coordinator image was amd64-only, so on an arm64 node it dies before the JVM starts with exec /opt/java/openjdk/bin/java: exec format error.

What changes

  • The image is now built by jib-maven-plugin from shard4j-coordinator/pom.xml instead of a Dockerfile, and published as one multi-arch index covering every Linux platform eclipse-temurin:25-jre publishes: linux/amd64, linux/arm64, linux/ppc64le, linux/s390x.
  • shard4j-coordinator/Dockerfile is removed so there is a single definition of the image.
  • build.yml's container-image job:
    • builds the smoke-test image with jib:dockerBuild (Jib picks the runner's platform);
    • pushes to a throwaway registry:2 service container and fails if any of the four platforms is missing from the index, so every PR proves the multi-arch path, not only main;
    • pushes to GHCR with jib:build, keeping the existing tags ($VERSION, sha-<12> on main, latest on release tags).

Why Jib rather than buildx + QEMU

  • Jib runs no RUN steps: it layers the app onto the matching base image per platform, so no emulation, and adding a platform is a pom entry.
  • Dependencies, the protocol snapshot and application classes are separate layers, so a typical change pushes a small layer rather than the whole fat jar.
  • Reproducible layer timestamps, and no dependence on whatever *-app.jar happens to sit in target/.

Windows is not built: the base image's windows/amd64 variants are Windows containers, which Jib cannot produce, and the numeric 10001:10001 user has no meaning there.

arm64 CI

build, coordinated-profile and container-image now also run on ubuntu-24.04-arm (free for public repositories), with fail-fast: false. The arm64 legs are named <job> (arm64); the amd64 legs keep their exact names, so the three required checks on main still match.

  • build (arm64) runs the whole reactor including every Testcontainers IT, natively on arm64.
  • coordinated-profile (arm64) runs the failsafe profile against a coordinator container on arm64.
  • container-image (arm64): jib:dockerBuild picks the runner's platform, so the smoke test boots the arm64 variant natively -- the exact image that failed with exec format error. The platform-index check and the GHCR push run only on the amd64 leg, so the image is pushed once.

The arm64 checks are not required checks yet, so Dependabot auto-merge would not wait for them. Adding them is a branch-protection change, left for a separate decision.

Details worth reviewing

  • /data ownership. Jib cannot chown, so a fresh named volume would be root-owned and the coordinator's exclusive lock on the data directory fails. jib-ownership-extension-maven chowns /data to 10001:10001; the directory comes from src/main/jib/data/, whose .keep placeholder is excluded from the image.
  • jib.skip is true in the parent and false in the coordinator, so mvn package jib:… works from the reactor root without the other modules trying to containerize. Jib is not bound to a lifecycle phase: the everyday build stays offline.
  • Entrypoint. The image now runs java -cp @/app/jib-classpath-file …CoordinatorApplication from exploded classes instead of java -jar app.jar. Deployments that override the command need updating; JAVA_TOOL_OPTIONS works either way. Startup to /healthz was ~3s locally.
  • The Testcontainers-based ITs build their own image from the app jar and are unaffected.

Verified locally

  • jib:dockerBuild image: /healthz answers with a named volume on /data; with no COORDINATOR_SECRETS it exits 1 and logs the variable name.
  • jib:build to a local registry:2 produced an index with all four platforms; the CI platform check passes against it.
  • mvn test passes.

…e image publishes

Signed-off-by: Marvin Froeder <velo.br@gmail.com>
…ers too

Signed-off-by: Marvin Froeder <velo.br@gmail.com>
@velo
velo merged commit 9f45c5a into main Sep 24, 2026
7 checks passed
@velo
velo deleted the multi-arch-image-via-jib branch September 24, 2026 19:33
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