I want to create a Docker image for aarch64 (Github here).
The image itself works on amd64 but on aarch64 with a command:
$ docker run --rm -it sineverba/serverless cat /etc/os-release
I get
exec /usr/local/bin/docker-entrypoint.sh: exec format error
This is the Dockerfile:
ARG NODE_VERSION=20.10.0
FROM --platform=$BUILDPLATFORM node:$NODE_VERSION-alpine3.19
# Set versions from Make, otherwise use default
## NPM
ARG NPM_VERSION=latest
ENV NPM_VERSION $NPM_VERSION
## SERVERLESS
ARG SERVERLESS_VERSION=latest
ENV SERVERLESS_VERSION $SERVERLESS_VERSION
# Update and upgrade
RUN apk update &&
apk upgrade --available --no-cache &&
rm -rf /var/cache/apk/*
# Install
RUN npm install -g npm@$NPM_VERSION && npm install -g serverless@$SERVERLESS_VERSION
# Set workdir
WORKDIR /app
and this is the command build launched from Semaphore CI:
docker buildx build
--platform linux/arm64/v8,linux/amd64,linux/arm/v6,linux/arm/v7
--build-arg NODE_VERSION=$NODE_VERSION
--build-arg NPM_VERSION=$NPM_VERSION
--build-arg SERVERLESS_VERSION=$SERVERLESS_VERSION
--tag $DOCKER_USERNAME/$DOCKER_IMAGE:$SEMAPHORE_GIT_TAG_NAME
--tag $DOCKER_USERNAME/$DOCKER_IMAGE:latest
--push "."
I would migrate from QEMU method, cause for JS binaries is very slow, more than 23 hours (!) in some case.
2
Answers
You have a single FROM in the Dockerfile:
The
--platform=$BUILDPLATFORM
says to pull the image for your local build platform instead of the target platform of the image being created. That means all of the binaries in the image are for your local platform, and the output is for your local platform. Building multiple instances of that, without some kind of cross compiler being used, is duplicating the effort to create the same image multiple times, and then falsely sticking a different platform label on it.In this case the slow version is the working version. Building a second amd64 image and putting an arm label on it isn’t going to have the desired result.
The choices for multi-platform images are:
You may use
QEMU's binfmt_misc
Should be available as default on Windows (Docker Desktop), and You may set it up over Linux [https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/fs/binfmt_misc.c?h=v5.19.6] as well.