Reputation: 303
I get this error on my github build:
The requested image's platform (linux/arm/v7) does not match the detected host platform (linux/amd64) and no specific platform was requested
The runner environment I'm using is the ubuntu:latest and my container uses arm32v7/node base image.
Here's my Dockerfile:
FROM arm32v7/node AS appbuild
WORKDIR /app
COPY package.json ./
COPY src/ ./src
RUN npm install
FROM appbuild as release
ENTRYPOINT ["npm", "start"]
And here's my deployment to github yaml:
jobs:
docker:
runs-on: ubuntu-latest
The jobs are ran inside a ubuntu runner environment. I suspect the arm version of the node image I'm using is unable to run in that environment, is that correct?
Edit:
- name: Build controller image
if: steps.changed-files-plantcontroller.outputs.any_changed == 'true'
run: >
docker build -t ${{ env.image_name_controller }} ${{ env.context }}
env:
context: ./controller
Upvotes: 4
Views: 7607
Reputation: 5218
You are correct. Docker on your arm64 build environment cannot build the arm32v7 image without Docker Buildx. You can solve this by using the buildx Github Action and qemu action, that prepares your environment to build multi-arch images.
Buildx is Docker's technology to build images for a target architecture not matching the host's (in this case the host arch is arm64
). You can read about how this works here.
QEMU is an emulator used by Docker buildx. It's a dependency I learned the hard way was needed when writing a multi-arch workflow.
For more reference, check out this doc: https://github.com/docker/build-push-action/blob/master/docs/advanced/multi-platform.md
You should be able to build your image with a workflow with something like this:
name: ci
on:
push:
branches:
- 'master'
jobs:
docker:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v2
-
name: Set up QEMU dependency
uses: docker/setup-qemu-action@v1
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Build controller image
if: steps.changed-files-plantcontroller.outputs.any_changed == 'true'
uses: docker/build-push-action@v2
with:
context: ${{ env.context }}
tags: ${{ env.image_name_controller }}
platforms: linux/arm/v7
push: true
env:
context: ./controller
NOTE: Updated the last build command with how you have your Build controller image
step written. It just translates the Docker command to how the Docker build-push-action builds.
An alternative command you could use in place of the build-push-action@v2
:
docker buildx build -t ${{ env.image_name_controller }} --platform linux/arm/v7 --push ${{ env.context }}
The command assumes you want to push to a GitHub repo with the tag.
Unrelated, but there's an opportunity to simplify your Dockerfile.
When you're using buildx, Docker can handle pulling the right arm32v7 version of the image when the image you're pulling has multiple versions. Check out the node image tags and you'll see linux/arm/v7
listed as one of the OS/Arch tags. What this means is you could simplify your FROM arm32v7/node AS appbuild
line to FROM node AS appbuild
if you think you want to build for a different architecture sometime.
For example:
amd64
and arm64
amd64
or arm64
image depending on TARGETPLATFORMUpvotes: 8