From 9a1875f6b48b6b461b0027cc18b49a022de8c703 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1bio=20Henrique=20Ara=C3=BAjo?= Date: Fri, 23 Oct 2026 16:34:06 -0300 Subject: [PATCH] build: build the Docker image without emulation The multi-arch image ran the whole build twice, the arm64 half under QEMU: the SvelteKit UI (about 4,000 Svelte files) and the Go compile in emulated Node and Go. The v0.2.2 image job ran past 55 minutes. Both build stages now run on the build machine's platform (BUILDPLATFORM): the UI is the same files for every architecture and Go cross-compiles with GOOS/GOARCH from TARGETPLATFORM. The final stage only copies files, so the QEMU setup step is gone. Without cache: amd64 72 s, arm64 82 s. --- .github/workflows/release.yml | 1 - Dockerfile | 13 +++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 33d6b08..5f19e5e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -76,7 +76,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: docker/setup-qemu-action@v3 - uses: docker/setup-buildx-action@v3 - uses: docker/login-action@v3 with: diff --git a/Dockerfile b/Dockerfile index c004848..30fcda4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,22 +1,27 @@ # syntax=docker/dockerfile:1 +# Both build stages run on the build machine's own architecture (BUILDPLATFORM): the UI is the +# same files everywhere and Go cross-compiles, so a multi-arch build never runs under emulation. + # 1. Web UI (static files embedded into the binary) -FROM oven/bun:1.4-alpine AS web +FROM --platform=$BUILDPLATFORM oven/bun:1.4-alpine AS web WORKDIR /src/web COPY web/package.json web/bun.lock ./ RUN bun install --frozen-lockfile COPY web/ ./ RUN bun run build -# 2. Server: pure Go, no cgo, so the result is one static file -FROM golang:1.26-alpine AS server +# 2. Server: pure Go, no cgo, so the result is one static file for the target platform +FROM --platform=$BUILDPLATFORM golang:1.26-alpine AS server +ARG TARGETOS +ARG TARGETARCH WORKDIR /src COPY go.mod go.sum ./ RUN go mod download COPY . . COPY --from=web /src/web/build ./web/build ARG VERSION=dev -RUN CGO_ENABLED=0 go build -trimpath -ldflags "-s -w -X github.com/LowBloat/LowLex/internal/server.Version=${VERSION}" -o /out/lowlex ./cmd/lowlex \ +RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH:-amd64} go build -trimpath -ldflags "-s -w -X github.com/LowBloat/LowLex/internal/server.Version=${VERSION}" -o /out/lowlex ./cmd/lowlex \ && mkdir -p /out/data # 3. Runtime: CA certificates (for translation providers), time zones and a non-root user