From 348976205bb811619e030d3a88c3cdc5f174b1af Mon Sep 17 00:00:00 2001 From: saltbo Date: Fri, 19 Jun 2026 15:56:00 -0400 Subject: [PATCH] perf(ci): cross-compile the Go CLI and build dev images amd64-only MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The docker-dev build took ~14 min, dominated by a ~12-min server-image build — its arm64 half runs under QEMU emulation (native better-sqlite3/sharp). - Dev images (:dev, :dev-cli) now build linux/amd64 only, skipping arm64 QEMU entirely. Releases stay multi-arch. (The primary dev consumer runs amd64.) - The Go CLI builder now runs on $BUILDPLATFORM and cross-compiles via GOOS/GOARCH (CGO off), so the release arm64 CLI builds natively instead of under QEMU — arm64 'go build' verified at ~5s vs emulated minutes. Adds go build/mod cache mounts for fast incremental rebuilds. --- .github/workflows/ci.yml | 7 +++++-- Dockerfile | 12 +++++++++--- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d4f4116f..c2a3a794 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -125,7 +125,9 @@ jobs: with: context: . push: true - platforms: linux/amd64,linux/arm64 + # Dev images are amd64-only to skip slow arm64 QEMU emulation + # (native better-sqlite3/sharp). Releases stay multi-arch. + platforms: linux/amd64 build-args: | APP_VERSION=dev APP_COMMIT=${{ github.sha }} @@ -139,7 +141,8 @@ jobs: context: . target: cli push: true - platforms: linux/amd64,linux/arm64 + # Dev images are amd64-only (see server image above). Releases stay multi-arch. + platforms: linux/amd64 build-args: | APP_VERSION=dev APP_COMMIT=${{ github.sha }} diff --git a/Dockerfile b/Dockerfile index 6180acdf..430222ee 100644 --- a/Dockerfile +++ b/Dockerfile @@ -22,12 +22,18 @@ ENV ZPAN_APP_COMMIT=${APP_COMMIT} RUN pnpm build:node \ && pnpm prune --prod --ignore-scripts -FROM golang:1.25 AS cli-builder +# Build on the native build platform and cross-compile to the target arch, so +# the arm64 image doesn't go through slow QEMU emulation. CGO is off, so Go +# cross-compiles cleanly. Build/mod caches make incremental rebuilds fast. +FROM --platform=$BUILDPLATFORM golang:1.25 AS cli-builder +ARG TARGETOS +ARG TARGETARCH WORKDIR /app/cmd COPY cmd/go.mod cmd/go.sum ./ -RUN go mod download +RUN --mount=type=cache,target=/go/pkg/mod go mod download COPY cmd ./ -RUN CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o /out/zpan . +RUN --mount=type=cache,target=/go/pkg/mod --mount=type=cache,target=/root/.cache/go-build \ + CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -trimpath -ldflags="-s -w" -o /out/zpan . FROM debian:bookworm-slim AS geoip-db ARG GEOIP_DB_MONTH=2026-06