From 7e030722a930de056967aba8cb17c3ce67f7513e Mon Sep 17 00:00:00 2001 From: Aculix Technologies Date: Sun, 16 Aug 2026 01:43:07 +0530 Subject: [PATCH] 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. --- Dockerfile | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index 64e5853..a1c0b76 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,14 @@ # 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 @@ -15,7 +24,7 @@ COPY . . # Build the application RUN npm run build -# Production stage +# Production stage — this one is built per target platform. FROM nginx:alpine # Copy built files from builder stage @@ -28,4 +37,4 @@ COPY --from=builder /app/dist /usr/share/nginx/html EXPOSE 80 # Start nginx -CMD ["nginx", "-g", "daemon off;"] \ No newline at end of file +CMD ["nginx", "-g", "daemon off;"]