fix: build once on the host arch, not once per target

The v2.0.0 image failed on linux/arm/v7. Vite bundles with Rolldown, which
has no 32-bit ARM musl binary:

  Cannot find module '@rolldown/binding-linux-arm-musleabihf'

That came in with the Vite upgrade, but the older problem is that the
builder stage was rebuilt per platform under QEMU, when its output is
static files that are identical everywhere.

Pinning the builder to $BUILDPLATFORM runs install and build once,
natively, then copies the result into each nginx image. armv7 works again,
and two emulated npm installs go away with it.
This commit is contained in:
Aculix Technologies
2026-08-16 01:43:07 +05:30
parent 6e00c0a814
commit 7e030722a9
+12 -3
View File
@@ -1,5 +1,14 @@
# Build stage # Build stage
FROM node:20-alpine AS builder #
# Pinned to the *build host's* architecture, not the target's. The output is
# static HTML, CSS and JS — byte-identical whatever the image will eventually
# run on — so emulating the target here buys nothing and costs a QEMU-emulated
# npm install and bundle on every extra platform.
#
# It is also required for linux/arm/v7: Vite bundles with Rolldown, which ships
# no 32-bit ARM musl binary, so `npm run build` cannot run inside that image at
# all.
FROM --platform=$BUILDPLATFORM node:20-alpine AS builder
WORKDIR /app WORKDIR /app
@@ -15,7 +24,7 @@ COPY . .
# Build the application # Build the application
RUN npm run build RUN npm run build
# Production stage # Production stage — this one is built per target platform.
FROM nginx:alpine FROM nginx:alpine
# Copy built files from builder stage # Copy built files from builder stage
@@ -28,4 +37,4 @@ COPY --from=builder /app/dist /usr/share/nginx/html
EXPOSE 80 EXPOSE 80
# Start nginx # Start nginx
CMD ["nginx", "-g", "daemon off;"] CMD ["nginx", "-g", "daemon off;"]