Multi-Arch Build With Docker Buildx and CircleCi
Arm architecture is a defacto in the world of IoT devices and nowadays more and more supported by the big tech industries.
Besides being a favorite container solution around the world, Docker also offers a number of interesting technologies including layers in file systems, isolation at the kernel level, and more.
Why Multi-Arch Build?
The main reason is that your need to support multiple platforms.
Another reason is that, for example, the docker image with amd64-x86 cannot be run in a system with arm64-aarch64 architecture and vice versa.
How We Can Build Multi-Arch Docker Images?
There is two option for building the image
- A native system with arm64 and amd64 ( for example raspberry pi or Nvidia Jetson ) or other supported architectures by docker. While I was writing this article, circleci added support for ARM machines thanks to graviton2 instances on Amazon EC2.
- Docker buildx for building the Multi-Arch images in the same machine and push with the same tag.
The native system always has better performance and build time will be dramatically better than buildx because the buildx using qemu-user-static for emulating the architecture and performance of emulation is not comparable with native arch.
So why we are using buildx when we know the performance of the native system is better?
The main reason is that Docker buildx build the images with different architecture at the same time and if we don't have a heavy build like a huge C++ base code it would be fast enough to ignore performance.
Secondly, when you build Docker images separately, you have to push the images separately, create a manifest, and push to your registry, which requires at least 3 steps while buildx only requires a single step.
The easy way: Buildx
Thanks Andriy Borodiychuk for collaborating in writing the circleci configuration examples.