From 34bb458b066ba20f8725e6d26b119caf49679009 Mon Sep 17 00:00:00 2001 From: Manuel Trezza <5673677+mtrezza@users.noreply.github.com> Date: Sun, 27 Sep 2026 08:39:49 +0200 Subject: [PATCH 1/2] ci: Docker build crashes with illegal instruction under arm64 emulation --- .github/workflows/ci.yml | 3 -- .github/workflows/release-automated.yml | 3 -- .github/workflows/release-manual-docker.yml | 1 + Dockerfile | 33 +++++++++++++++++---- 4 files changed, 28 insertions(+), 12 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0b3e7e4339..da9a6f35fb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -149,9 +149,6 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v4 - - name: Set up QEMU - id: qemu - uses: docker/setup-qemu-action@v2 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2 - name: Build docker image diff --git a/.github/workflows/release-automated.yml b/.github/workflows/release-automated.yml index 58bcc400be..f25d7d2ec4 100644 --- a/.github/workflows/release-automated.yml +++ b/.github/workflows/release-automated.yml @@ -54,9 +54,6 @@ jobs: uses: actions/checkout@v4 with: ref: ${{ needs.release.outputs.current_tag }} - - name: Set up QEMU - id: qemu - uses: docker/setup-qemu-action@v2 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2 - name: Log into Docker Hub diff --git a/.github/workflows/release-manual-docker.yml b/.github/workflows/release-manual-docker.yml index 3b7ee8c0ab..8441e5cda3 100644 --- a/.github/workflows/release-manual-docker.yml +++ b/.github/workflows/release-manual-docker.yml @@ -26,6 +26,7 @@ jobs: uses: actions/checkout@v4 with: ref: ${{ github.event.inputs.ref }} + # Emulation is only needed for refs with a Dockerfile that runs commands on the target platform - name: Set up QEMU id: qemu uses: docker/setup-qemu-action@v2 diff --git a/Dockerfile b/Dockerfile index adb559ad44..6d6e8a9f52 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,11 @@ ############################################################ # Build stage ############################################################ -FROM node:20.19.0-alpine3.20 AS build +# Runs on the platform of the build machine, also when building the image for +# another platform, so that no code runs under emulation; Node.js running under +# QEMU emulation can crash with an illegal instruction. Builders that don't set +# BUILDPLATFORM, like the legacy Docker builder, run it on their own platform. +FROM --platform=${BUILDPLATFORM:-linux} node:20.19.0-alpine3.20 AS build RUN apk --no-cache add \ build-base \ @@ -16,23 +20,40 @@ COPY package*.json ./ # Copy src to have config files for install COPY . . -# Increase npm network timeout and retries for slow platforms (e.g. arm64 via QEMU) +# Increase npm network timeout and retries to tolerate network errors ENV npm_config_fetch_retries=5 ENV npm_config_fetch_retry_mintimeout=60000 ENV npm_config_fetch_retry_maxtimeout=300000 -# Install without scripts -RUN npm ci --omit=dev --ignore-scripts \ +# Architecture of the image to build, set by BuildKit; builders that don't set +# it build the image for their own platform +ARG TARGETARCH + +# Install production dependencies for the image platform without scripts +RUN arch="${TARGETARCH:-$(uname -m)}" \ + && case "$arch" in \ + amd64|x86_64) cpu=x64 ;; \ + arm64|aarch64) cpu=arm64 ;; \ + arm|armv6l|armv7l) cpu=arm ;; \ + ppc64le) cpu=ppc64 ;; \ + s390x) cpu=s390x ;; \ + *) echo "Unsupported target architecture: '$arch'" >&2; exit 1 ;; \ + esac \ + && npm ci --omit=dev --ignore-scripts --os=linux --cpu="$cpu" --libc=musl \ # Copy production node_modules aside for later && cp -R node_modules prod_node_modules \ # Install all dependencies && npm ci \ # Run build steps - && npm run build + && npm run build \ + # Create empty logs folder for the release stage + && mkdir /logs ############################################################ # Release stage ############################################################ +# Must not contain RUN instructions, because building the image for another +# platform than the one of the build machine would then require emulation. FROM node:20.19.0-alpine3.20 AS release VOLUME /parse-server/cloud /parse-server/config @@ -47,7 +68,7 @@ COPY package*.json ./ COPY bin bin COPY public public COPY views views -RUN mkdir -p logs && chown -R node: logs +COPY --from=build --chown=node:node /logs logs ENV PORT=1337 USER node From 4aa417384ee75028ad2b0fa57522f3abd8ab206d Mon Sep 17 00:00:00 2001 From: Manuel Trezza <5673677+mtrezza@users.noreply.github.com> Date: Sun, 27 Sep 2026 15:37:12 +0200 Subject: [PATCH 2/2] ci: Remove QEMU from manual Docker release workflow --- .github/workflows/release-manual-docker.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/release-manual-docker.yml b/.github/workflows/release-manual-docker.yml index 8441e5cda3..0211a2877b 100644 --- a/.github/workflows/release-manual-docker.yml +++ b/.github/workflows/release-manual-docker.yml @@ -26,10 +26,6 @@ jobs: uses: actions/checkout@v4 with: ref: ${{ github.event.inputs.ref }} - # Emulation is only needed for refs with a Dockerfile that runs commands on the target platform - - name: Set up QEMU - id: qemu - uses: docker/setup-qemu-action@v2 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2 - name: Log into Docker Hub