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.
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 all
Then we can build the multi-arch docker image like below:
$ docker build --platform linux/amd64,linux/arm64 .
Another strategy is to use the buildx
command, which is a new feature of the docker engine. The buildx
command is a CLI plugin that extends the docker command with the full support of the features provided by Moby BuildKit builder toolkit. To use the buildx
command, we need to install the buildx
plugin first. For MacOS, the buildx
plugin is already included in the docker desktop, for Debian, we need to install the buildx
plugin manually like below:
# debian
(root)# apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Then we can use the buildx
command to build the multi-arch docker images.
$ docker buildx build --platform linux/amd64,linux/arm64 .
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,
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.