Since Apple announces M1 Macbook in 2020, the CPU market became complex. At least in the server CPU market, Intel X86 has been one and only for a long time. Developers did not need to know what CPU architecture their computers use since AMD64 is the thing in most cases.
As the M1 users got common in the company, my team decided to support M1 native docker images for colleagues. My team assigned the task to me and I needed to check what is necessary.
Fortunately, Docker was supporting multi-architecture by its experimental library called buildx
. You might have heard of buildx
if you have ever tried Docker cache.
The command is simple.
docker buildx build --platform linux/arm64,linux/amd64 --push .
The different point is to add --platform
argument and put linux/arm64
, linux/amd64
together. Of course, you need to preprocess something to use buildx
, however, I will skip the detail in this article since it is easy.
I was managing the arguments to build images by docker-compose
. Many build-args exist and it was obviously inefficient to migrate it outside of the yaml file just for buildx
. I needed a breakthrough.
I could resolve it by finding out bake
which is a high level feature for buildx. bake
was made to support file-based docker configurations such as yaml
of docker-compose and hcl
. Thus, the command looked like the one below.
docker buildx bake --platform linux/arm64,linux/amd64 --push -f docker-compose.yml target
If you do not like too many arguments on command, x-bake
is a good alternative referred to this article. For example,
x-bake:
tags:
- registry/image:1234
- registry/image:latest
platforms:
- linux/arm64
- linux/amd64
pull: true
Otherwise, you can tag it via the below command as well.
docker buildx bake --set "*.tag=registry/image:1234" --set "*.tag=registry/image:latest" -f docker-compose.yml target
Since I did not a heavy benchmark, I can only give you the result of mine. On my side, npm run build
and pip install
were faster by 3x to 5x on arm64 native, which means that it was 3x to 5x slower on the emulated amd64. An interesting point is a reversed result on amd64-native. The emulated arm64 was much slower than amd64. At the very least, I can confirm that the native build is worthy and the emulated build works properly even though it is a bit slow.