diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 63c6106..d291a2c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,4 +29,5 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - run: docker build . + - uses: docker/setup-buildx-action@v3 + - run: docker buildx build --platform linux/amd64,linux/arm64 . diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index d55ceb5..efc05a9 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -59,7 +59,7 @@ jobs: uses: docker/build-push-action@v6 with: context: . - platforms: linux/amd64 + platforms: linux/amd64,linux/arm64 push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} diff --git a/Dockerfile b/Dockerfile index 5358c7f..1da1c4d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,11 @@ -# Build both the proxy and the test mock as static binaries. -FROM golang:1.26 AS build +# Build both the proxy and the test mock as static binaries. The build stage +# runs natively on the builder and cross-compiles for the target platform, so +# multi-arch builds need no emulation. +FROM --platform=$BUILDPLATFORM golang:1.26 AS build WORKDIR /src COPY . . +ARG TARGETOS +ARG TARGETARCH ARG VERSION ARG COMMIT ARG BUILD_DATE @@ -25,8 +29,9 @@ RUN set -eu; \ d="${BUILD_DATE:-$(date -u +%Y-%m-%dT%H:%M:%SZ)}"; \ dirty_flag="${DIRTY:-unknown}"; \ ldflags="-s -w -X main.version=$v -X main.commit=$c -X main.buildDate=$d -X main.dirty=$dirty_flag"; \ - CGO_ENABLED=0 go build -trimpath -buildvcs=false -ldflags "$ldflags" -o /out/steady-proxy .; \ - CGO_ENABLED=0 go build -trimpath -buildvcs=false -o /out/testupstream ./testupstream + export CGO_ENABLED=0 GOOS="$TARGETOS" GOARCH="$TARGETARCH"; \ + go build -trimpath -buildvcs=false -ldflags "$ldflags" -o /out/steady-proxy .; \ + go build -trimpath -buildvcs=false -o /out/testupstream ./testupstream # Minimal runtime; distroless/static ships CA certs (needed for upstream TLS). FROM gcr.io/distroless/static-debian12 diff --git a/README.md b/README.md index 920f944..f140887 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ curl -fsS http://127.0.0.1:8789/__version ### Prebuilt container image -Linux `amd64` images are published to GitHub Container Registry: +Linux `amd64` and `arm64` images are published to GitHub Container Registry: ```bash docker pull ghcr.io/xllent-ai/steady-proxy:latest diff --git a/docs/RELEASING.md b/docs/RELEASING.md index 9fd602f..76eee2b 100644 --- a/docs/RELEASING.md +++ b/docs/RELEASING.md @@ -46,7 +46,7 @@ All steps use GitHub's built-in `GITHUB_TOKEN`; no external secrets are required ## Container images -The [container workflow](../.github/workflows/docker-publish.yml) publishes Linux `amd64` images to `ghcr.io/xllent-ai/steady-proxy`: +The [container workflow](../.github/workflows/docker-publish.yml) publishes multi-arch Linux `amd64` and `arm64` images to `ghcr.io/xllent-ai/steady-proxy`: - **Push to `main`:** Publishes `latest` and `sha-`. - **Release published:** Publishes `` (e.g., `v0.1.1`) and `sha-`. Release builds never overwrite `latest`.