From 3eec79fa44629803f184d538b32632d7f6a07869 Mon Sep 17 00:00:00 2001 From: Aneurin Barker Snook Date: Thu, 8 Oct 2026 16:19:14 +0100 Subject: [PATCH] Build multi-platform image for linux/amd64 and linux/arm64 The builder stage cross-compiles Caddy for the target platform, so no emulation is needed. The module check runs against the amd64 image; PR checks also build arm64. Co-Authored-By: Claude Opus 5.5 --- .gitea/workflows/build.yml | 18 ++++++++++++++---- .gitea/workflows/pr-checks.yml | 10 +++++++++- Dockerfile | 8 ++++++-- README.md | 2 +- 4 files changed, 30 insertions(+), 8 deletions(-) diff --git a/.gitea/workflows/build.yml b/.gitea/workflows/build.yml index 9d3953e..296e694 100644 --- a/.gitea/workflows/build.yml +++ b/.gitea/workflows/build.yml @@ -21,11 +21,16 @@ jobs: - uses: actions/checkout@v4 + - name: Set up Docker buildx + run: | + docker buildx rm multi 2>/dev/null || true + docker buildx create --name multi --driver docker-container --use + - name: Build - run: docker build --pull --tag "$IMAGE:latest" . + run: docker buildx build --pull --platform linux/amd64 --tag "$IMAGE:check" --load . - name: Check the deSEC module is built in - run: docker run --rm "$IMAGE:latest" caddy list-modules | grep -x dns.providers.desec + run: docker run --rm "$IMAGE:check" caddy list-modules | grep -x dns.providers.desec - name: Log in to the container registry env: @@ -40,5 +45,10 @@ jobs: echo "No existing :latest to promote; skipping." fi - - name: Push "latest" - run: docker push "$IMAGE:latest" + - name: Build and push multi-arch "latest" + run: | + docker buildx build \ + --platform linux/amd64,linux/arm64 \ + --tag "$IMAGE:latest" \ + --push \ + . diff --git a/.gitea/workflows/pr-checks.yml b/.gitea/workflows/pr-checks.yml index 7705288..3c68353 100644 --- a/.gitea/workflows/pr-checks.yml +++ b/.gitea/workflows/pr-checks.yml @@ -16,8 +16,16 @@ jobs: - uses: actions/checkout@v4 + - name: Set up Docker buildx + run: | + docker buildx rm multi 2>/dev/null || true + docker buildx create --name multi --driver docker-container --use + - name: Build - run: docker build --pull --tag caddy-desec-docker:check . + run: docker buildx build --pull --platform linux/amd64 --tag caddy-desec-docker:check --load . + + - name: Build arm64 + run: docker buildx build --pull --platform linux/arm64 . - name: Check the deSEC module is built in run: docker run --rm caddy-desec-docker:check caddy list-modules | grep -x dns.providers.desec diff --git a/Dockerfile b/Dockerfile index e3b608f..3fc2ce1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,12 @@ # Caddy with the caddy-dns/desec module, for ACME DNS-01 challenges against # zones hosted at deSEC. Otherwise the stock caddy:2-alpine image. -FROM caddy:2-builder AS builder -RUN xcaddy build --with github.com/caddy-dns/desec +# The builder runs on the build host and cross-compiles for the target +# platform, so multi-platform builds need no emulation. +FROM --platform=$BUILDPLATFORM caddy:2-builder AS builder +ARG TARGETOS TARGETARCH +RUN CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH \ + xcaddy build --with github.com/caddy-dns/desec FROM caddy:2-alpine COPY --from=builder /usr/bin/caddy /usr/bin/caddy diff --git a/README.md b/README.md index 789e559..8b6cfc2 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Stock [Caddy](https://caddyserver.com) plus the [caddy-dns/desec](https://github.com/caddy-dns/desec) module, so Caddy can get certificates by ACME DNS-01 against a zone hosted at [deSEC](https://desec.io). Published as -`code.aneur.in/cloud/caddy-desec-docker:latest` (linux/amd64). +`code.aneur.in/cloud/caddy-desec-docker:latest` (linux/amd64, linux/arm64). Used by the `llm` stack in [cloud/cloud](https://code.aneur.in/cloud/cloud) for `*.llm.aneur.in`: