Building Docker Image with Multi-arch Support
Cross-platform deployment is a common requirement for modern software development. The multi-arch docker image is a good practice for cross-platform deployment. Especially, if the docker image has to be deployed in the different CPU architectures, the multi-arch docker image will provide the best performance and compatibility. For example, if the docker engine is running on the arm64 CPU, the arm64 docker image will be pulled and executed, if no arm64 docker image is available, another arch docker image like amd64 will be pulled. This is a run-time emulation, and the performance will be abysmal.
How to build a multi-arch docker image
To build a multi-arch docker image, the official guide is available.
-
We can use different strategies, one is real-time emulation with
qemu, to achieve this, just execute the command below:$ docker run --privileged --rm tonistiigi/binfmt --install allThen we can build the multi-arch docker image like below:
$ docker build --platform linux/amd64,linux/arm64 . -
Another strategy is to use the
buildxcommand, which is a new feature of the docker engine. Thebuildxcommand is a CLI plugin that extends the docker command with the full support of the features provided by Moby BuildKit builder toolkit. To use thebuildxcommand, we need to install thebuildxplugin first. For MacOS, thebuildxplugin is already included in the docker desktop, for Debian, we need to install thebuildxplugin manually like below:# debian (root)# apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-pluginThen we can use the
buildxcommand to build the multi-arch docker images.$ docker buildx build --platform linux/amd64,linux/arm64 .
Optimize the build process
Generally, previous guide are based on full emulation in building. When the multi-arch packages are pre-compiled, and we just install them in the building process, the performance is still acceptable. But if the compilation is required, the performance will be abysmal, because the full-emulation compilation is too slow.
To optimize this, please follow the guide. Generally, we’re using a cross-compilation toolchain to build the multi-arch packages, and then install them in the building process. The performance will be improved significantly.
For example, to build an arm64 docker image,
- the native way is to build with arm64 hardware
- the emulator way is to build the arm64 packages on the amd64 machine with full-emulation
- the cross way is to build the arm64 packages on the amd64 machine with the arm64 toolchain
| native | emulator | cross | |
|---|---|---|---|
| machine | arm64 | amd64 | amd64 |
| compiler | arm64 | arm64 | amd64 |
| target | arm64 | arm64 | arm64 |
The cross way is the best choice for the multi-arch docker image building when the hardware and the native way are not available.