Skip to content

Commit 7a6a93d

Browse files
fylornclaude
andauthored
Stop building the web image's frontend under QEMU (#24)
The Web Build & Push job for 633f641 on main was cancelled at GitHub's six-hour limit. Dockerfile.web built its builder stage once per target platform, so the arm64 leg ran `pnpm install` and `pnpm build` under QEMU. Node crashed there with SIGILL ("qemu: uncaught target signal 4") 40 seconds into the install; the step never exited, and the job sat idle until GitHub killed it. dist/ is static files, identical for every architecture. The builder stage now runs on $BUILDPLATFORM, so it is built once, natively, and only the COPY-only nginx stage is produced per architecture: nothing executes under emulation. Emulated, `pnpm build` alone took 260s against 23s natively. The job also gets a 20-minute timeout, so a hang fails in minutes instead of holding a runner for six hours. release.yml builds each architecture on its own native runner, where $BUILDPLATFORM already equals the target, so release images are built exactly as before. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent 633f641 commit 7a6a93d

3 files changed

Lines changed: 28 additions & 2 deletions

File tree

‎.github/workflows/ci.yml‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,13 +232,20 @@ jobs:
232232
$(printf "${IMAGE}@sha256:%s " *)
233233
234234
# ---------------------------------------------------------------------------
235-
# Docker Web: static files are arch-independent, single buildx with QEMU
235+
# Docker Web: static files are arch-independent. Dockerfile.web builds them
236+
# once on this runner's own platform and copies them into each arch's nginx
237+
# image, so no build step runs under emulation.
236238
# ---------------------------------------------------------------------------
237239
docker-web:
238240
name: Web Build & Push
239241
runs-on: ubuntu-latest
240242
needs: [rust, frontend]
241243
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
244+
# A healthy run takes minutes. With no limit, a hung build holds the
245+
# runner for GitHub's six-hour maximum — which is what happened when
246+
# Node crashed under QEMU in the old per-arch build and the step never
247+
# exited.
248+
timeout-minutes: 20
242249
permissions:
243250
contents: read
244251
packages: write

‎CHANGELOG.md‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,18 @@ target.
1111

1212
## [Unreleased]
1313

14+
### Fixed
15+
16+
- **CI** — the `main` push that merged #23 never produced its web image.
17+
`Dockerfile.web` built the frontend once per architecture, Node crashed
18+
with SIGILL in the QEMU-emulated arm64 build, and the build step hung
19+
until GitHub cancelled the job at the six-hour limit. The static files
20+
are identical on every architecture, so they are now built once,
21+
natively, and copied into each architecture's nginx image — emulated,
22+
`pnpm build` alone took 260s against 23s. The job also times out after
23+
20 minutes. Image contents are unchanged; release builds already ran on
24+
native runners.
25+
1426
## [1.0.2] — 2026-09-13
1527

1628
The shared gateway layer moves out into its own repository, and OIDC

‎deploy/docker/Dockerfile.web‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
# Stage 1: Build
2-
FROM node:24-alpine AS builder
2+
#
3+
# Runs on the building machine's own platform rather than once per target.
4+
# dist/ is static files, identical for every architecture, so it is built
5+
# once, natively, and stage 2 only copies it. Built per target, arm64 ran
6+
# `pnpm install` and `pnpm build` under QEMU: the build alone took 260s
7+
# against 23s natively, and when Node crashed there with SIGILL the step
8+
# never exited — the CI job sat idle until GitHub's six-hour limit.
9+
FROM --platform=$BUILDPLATFORM node:24-alpine AS builder
310

411
# Pin pnpm to a known-good 11.x. The workspace YAML's `allowBuilds`
512
# field requires pnpm 11+ (see web/pnpm-workspace.yaml top comment).

0 commit comments

Comments
 (0)