Armv7 docker image created with QEMU action causes Illegal instruction

I build my docker images on Github, for three architectures at once. For the backend, I had to go through hoops and instead using node:latest, use ubuntu:latest so that I can use glibc >= 2.29. However, it looks like launching anything that is installed when building that file - so npm or nodejs - will cause the image to crash on armv7, while working on x86_64:

backend_1   | #
backend_1   | # Fatal error in , line 0
backend_1   | # unreachable code
backend_1   | #
backend_1   | #
backend_1   | #
backend_1   | #FailureMessage Object: 0xbecf23ecIllegal instruction (core dumped)

Here is the Dockerfile:

FROM ubuntu:latest
ENV DEBIAN_FRONTEND=noninteractive
RUN apt update
RUN apt install nodejs npm -y
RUN apt install ca-certificates -y
RUN update-ca-certificates --fresh
RUN npm install -g npm@latest
WORKDIR /code
EXPOSE 4000
COPY package*.json ./
RUN npm i
COPY . .
VOLUME /code/media
CMD "npm" "start"

And the relevant action:

runs-on: ubuntu-latest
steps:
  - uses: actions/checkout@v2
  -
    name: Set up QEMU
    uses: docker/setup-qemu-action@v1
  -
    name: Set up Docker Buildx
    uses: docker/setup-buildx-action@v1
  -
    name: Login to DockerHub
    uses: docker/login-action@v1 
    with:
      username: ${{ secrets.DOCKERHUB_USERNAME }}
      password: ${{ secrets.DOCKERHUB_TOKEN }}
  -
    name: Build and push
    id: docker_build
    uses: docker/build-push-action@v2
    with:
      push: true
      tags: XXXXXXXXXX/backend:latest
      context: backend
      file: ./backend/Dockerfile
      platforms: linux/amd64,linux/arm64,linux/arm/v7
  -
    name: Image digest
    run: echo ${{ steps.docker_build.outputs.digest }}

I assume the problem is using apt while using QEMU actions (which are, AFAIK, behind the hood buildx commands)? If there is a fix for that, I’m happy to take it. If there is a way to get node/npm and glibc >= 2.29 at the same time, without using apt, then I’m happy about that solution too. Basically anything that helps my mess works for me!

Thank you very much for your help!

I’m seeing something very similar when running dart2native when building an armv7 container (it works fine with amd64 and arm64).

#26 [linux/arm/v7 stage-0 4/4] RUN dart2native /app/platform.dart -o /app/platform
#26 sha256:8dfddb27285d806e5cebf1fb002a0c2c632fd65ccb314e3ac8499208550373d1
#26 0.506 ../../runtime/vm/cpu_arm.cc: 151: error: Unrecognized ARM CPU architecture.
#26 0.507 version=2.12.4 (stable) (Thu Apr 15 12:26:53 2021 +0200) on "linux_arm"
#26 0.508 pid=7, thread=7, isolate_group=vm-isolate(0xff7f8000), isolate=vm-isolate(0xffa04000)
#26 0.508 isolate_instructions=fea18a80, vm_instructions=fea18a80
#26 0.511   pc 0xfebb6ea9 fp 0xfd2a6a30 dart::Profiler::DumpStackTrace(void*)+0x4c
#26 0.512   pc 0xfea18b6d fp 0xfd2a6a40 dart::Assert::Fail(char const*, ...)+0x1c
#26 0.513   pc 0xfeb17e19 fp 0xfd2a6a68 dart::HostCPUFeatures::Init()+0x17c
#26 0.516   pc 0xfeb183b7 fp 0xfd2a6b78 dart::Dart::Init(unsigned char const*, unsigned char const*, _Dart_Isolate* (*)(char const*, char const*, char const*, char const*, Dart_IsolateFlags*, void*, char**), bool (*)(void**, char**), void (*)(void*, void*), void (*)(void*, void*), void (*)(void*), void (*)(), void* (*)(char const*, bool), void (*)(unsigned char**, int*, void*), void (*)(void const*, int, void*), void (*)(void*), bool (*)(unsigned char*, int), _Dart_Handle* (*)(), bool, Dart_CodeObserver*)+0x346
#26 0.517   pc 0xfeec4e59 fp 0xfd2a6bd8 Dart_Initialize+0x54
#26 0.518   pc 0xfea0a03b fp 0xfd2a6c90 dart::bin::main(int, char**)+0x2be
#26 0.519   pc 0xfea0ac9b fp 0xfd2a6ca0 main+0xa
#26 0.519 -- End of DumpStackTrace
#26 0.657 qemu: uncaught target signal 6 (Aborted) - core dumped
#26 0.925 Aborted (core dumped)
#26 ERROR: executor failed running [/bin/sh -c dart2native /app/platform.dart -o /app/platform]: exit code: 134