#!/usr/bin/env bash # Builds the server image for the Pi (arm64) and x86 hosts (amd64) and pushes it # to the registry, tagged `latest` and with the commit it was built from. # # The Pi never builds: deploy/docker-compose.pi.yml pulls what this pushes. # Only a clean working tree is built, so a commit tag names exactly the code in # that commit — a tag built from uncommitted edits would name nothing. # # npm run publish-image # registry.mc02.dev/schulcloud-mcp # IMAGE=registry.example/other npm run publish-image set -euo pipefail IMAGE=${IMAGE:-registry.mc02.dev/schulcloud-mcp} PLATFORMS=${PLATFORMS:-linux/amd64,linux/arm64} cd "$(dirname "$0")/.." if [ -n "$(git status --porcelain)" ]; then echo "The working tree has uncommitted changes. Commit them first: the image's tag must name exactly one commit." >&2 exit 1 fi # An x86 machine builds arm64 under QEMU emulation, which has to be registered # once per boot. Registering needs a privileged container, so say how rather # than doing it unasked. if [[ "$PLATFORMS" == *linux/arm64* ]] && ! docker buildx inspect | grep -q 'linux/arm64'; then echo "This builder cannot build linux/arm64. Register emulation (lasts until the next reboot) with:" >&2 echo " docker run --privileged --rm tonistiigi/binfmt --install arm64" >&2 exit 1 fi revision=$(git rev-parse HEAD) tag=$(git rev-parse --short HEAD) # One multi-platform push needs either Docker's containerd image store or a # docker-container builder (`docker buildx create --use`); buildx says which # is missing if neither is there. docker buildx build \ --platform "$PLATFORMS" \ --tag "$IMAGE:latest" \ --tag "$IMAGE:$tag" \ --label org.opencontainers.image.title=schulcloud-mcp \ --label org.opencontainers.image.source=https://git.mc02.dev/fabi/Schulcloud-MCP \ --label "org.opencontainers.image.revision=$revision" \ --label "org.opencontainers.image.created=$(date -u +%Y-%m-%dT%H:%M:%SZ)" \ --push . echo "Pushed $IMAGE:$tag and $IMAGE:latest for $PLATFORMS."