Error building docker image for different platform/arch on M1 mac
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 7.2k
- Forks
- 1.7k
- Avg merge
- 13d 8h
- Merged PRs (30d)
- 2
Description
Problem occured when building linux/amd64 image (by setting platform parameter) on M1 mac for different arch. I isolated a case for this bug and found workaround.
The problem is when building an image which has:
scratchas a base image- platform different than current platform, e.g. building 'linux/amd64' image on M1 mac, or building 'linux/arm64' image on amd64 machine (I tested both cases)
- ARG as the first operation
The problem does not occur when the base image is changed to anything else (e.g. ubuntu), or platform switch is not set, or there is different first op than ARG.
Build fails from code
Dockerfile:
FROM scratch
ARG dummy_arg
ADD file2.txt /data/file2.txt
Run with code:
client = docker.client.from_env()
_, _ = client.images.build(path="context", dockerfile="Dockerfile", tag="test-image", platform="linux/amd64", nocache=True)
Results in:
DEBUG:docker.api.build:Looking for auth config
DEBUG:docker.api.build:Sending auth config ()
DEBUG:urllib3.connectionpool:http://localhost:None "POST /v1.41/build?t=test-image-3494&q=False&nocache=True&rm=False&forcerm=False&pull=False&dockerfile=Dockerfile&platform=linux%2Famd64 HTTP/1.1" 200 None
Traceback (most recent call last):
File "/Users/lsierant/mdb/sonar-fix/test.py", line 11, in <module>
_, _ = client.images.build(path="context", dockerfile="Dockerfile", tag=image_name, platform="linux/amd64", nocache=True)
File "/Users/lsierant/mdb/sonar-fix/venv/lib/python3.9/site-packages/docker/models/images.py", line 285, in build
raise BuildError(chunk['error'], result_stream)
docker.errors.BuildError: failed to get destination image "sha256:5b89a558a786c4b82412c56c53bfdf715817ab99cd7e63bd08b496a696060c36": image with reference sha256:5b89a558a786c4b82412c56c53bfdf715817ab99cd7e63bd08b496a696060c36 was found but does not match the specified platform: wanted linux/amd64, actual: linux/arm64```
Build succeeds from cli
The same dockerfile built from cli is working correctly.
$ docker build . --platform "linux/amd64" --no-cache -t test-image
[+] Building 0.1s (5/5) FINISHED
=> => transferring dockerfile: 36B
=> [internal] load .dockerignore
=> => transferring context: 2B
=> [internal] load build context => => transferring context: 30B
=> [1/1] ADD file2.txt /data/file2.txt
=> exporting to image => => exporting layers
=> => writing image sha256:fb7f611c51c95f880cbeabf3a77067dafa8cd9cb961a6564bcba035fcc0ecef9
=> => naming to docker.io/library/test-image
Workaround
It seems that this error occurs only when having scratch image as a base and ARG as a second command. After swapping ARG and ADD lines the image is building. Also changing the base image to anything different than scratch is working.
FROM scratch
ADD file2.txt /data/file2.txt
ARG dummy_arg
Results in:
DEBUG:urllib3.connectionpool:http://localhost:None "POST /v1.41/build?t=test-image-5877&q=False&nocache=True&rm=False&forcerm=False&pull=False&dockerfile=Dockerfile.ok&platform=linux%2Famd64 HTTP/1.1" 200 None
DEBUG:urllib3.connectionpool:http://localhost:None "GET /v1.41/images/4491aba34a0f/json HTTP/1.1" 200 None
Steps to recreate
I created sample project when trying to pin down the issue: https://github.com/lsierant/playground-docker-py
git clone https://github.com/lsierant/playground-docker-py.git./run-test.sh(setups venv and runs test.py)
Environment
I tested it on M1 mac (building linux/arm64) and on linux machine building arm64 image.
pip freeze | grep docker && python --version && docker version
Python 3.9.13
Client:
Cloud integration: v1.0.24
Version: 20.10.14
API version: 1.41
Go version: go1.16.15
Git commit: a224086
Built: Thu Mar 24 01:49:20 2022
OS/Arch: darwin/arm64
Context: default
Experimental: true
Server: Docker Desktop 4.8.2 (79419)
Engine:
Version: 20.10.14
API version: 1.41 (minimum version 1.12)
Go version: go1.16.15
Git commit: 87a90dc
Built: Thu Mar 24 01:45:44 2022
OS/Arch: linux/arm64
Experimental: false
containerd:
Version: 1.5.11
GitCommit: 3df54a852345ae127d1fa3092b95168e4a88e2f8
runc:
Version: 1.0.3
GitCommit: v1.0.3-0-gf46b6ba
docker-init:
Version: 0.19.0
GitCommit: de40ad0
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the reproducer's test.py and Dockerfile, then inspect client.images.build and compare its request with the successful docker build command. Use run-test.sh to reproduce the scratch-plus-ARG case on a different target platform; done means the Python client builds the image successfully with the same parameters.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- docker, python
- Domain
- api, devops
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100