Untitled

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.

Buildx

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.

What is the problem?

docker-compose.yml

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 bakewhich 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

Performance

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.

Limitation