The "classic" image store of the Docker Engine does not support multi-platform
images. Switching to the containerd image store ensures that your Docker Engine
can push, pull, and build multi-platform images.
Creating a custom builder that uses a driver with multi-platform support,
such as the `docker-container` driver, will let you build multi-platform images
without switching to a different image store. However, you still won't be able
to load the multi-platform images you build into your Docker Engine image
store. But you can push them to a container registry directly with `docker
build --push`.
{{< tabs >}}
{{< tab name="containerd image store" >}}
The steps for enabling the containerd image store depends on whether you're
using Docker Desktop or Docker Engine standalone:
- If you're using Docker Desktop, enable the containerd image store in the
[Docker Desktop settings](/manuals/desktop/features/containerd.md).
- If you're using Docker Engine standalone, enable the containerd image store
using the [daemon configuration file](/manuals/engine/storage/containerd.md).
{{< /tab >}}
{{< tab name="Custom builder" >}}
To create a custom builder, use the `docker buildx create` command to create a
builder that uses the `docker-container` driver.
```console
$ docker buildx create \
--name container-builder \
--driver docker-container \
--bootstrap --use
```
> [!NOTE]
> Builds with the `docker-container` driver aren't automatically loaded to your
> Docker Engine image store. For more information, see [Build
> drivers](/manuals/build/builders/drivers/_index.md).
{{< /tab >}}
{{< /tabs >}}
If you're using Docker Engine standalone and you need to build multi-platform
images using emulation, you also need to install QEMU, see [Install QEMU
manually](#install-qemu-manually).
## Build multi-platform images
When triggering a build, use the `--platform` flag to define the target
platforms for the build output, such as `linux/amd64` and `linux/arm64`:
```console
$ docker buildx build --platform linux/amd64,linux/arm64 .
```
## Strategies
You can build multi-platform images using three different strategies,
depending on your use case:
1. Using emulation, via [QEMU](#qemu)
2. Use a builder with [multiple native nodes](#multiple-native-nodes)
3. Use [cross-compilation](#cross-compilation) with multi-stage builds
### QEMU
Building multi-platform images under emulation with QEMU is the easiest way to
get started if your builder already supports it. Using emulation requires no
changes to your Dockerfile, and BuildKit automatically detects the
architectures that are available for emulation.
> [!NOTE]
>
> Emulation with QEMU can be much slower than native builds, especially for
> compute-heavy tasks like compilation and compression or decompression.
>
> Use [multiple native nodes](#multiple-native-nodes) or
> [cross-compilation](#cross-compilation) instead, if possible.
Docker Desktop supports running and building multi-platform images under
emulation by default. No configuration is necessary as the builder uses the
QEMU that's bundled within the Docker Desktop VM.
#### Install QEMU manually
If you're using a builder outside of Docker Desktop, such as if you're using
Docker Engine on Linux, or a custom remote builder, you need to install QEMU
and register the executable types on the host OS. The prerequisites for
installing QEMU are:
- Linux kernel version 4.8 or later
- `binfmt-support` version 2.1.7 or later
- The QEMU binaries must be statically compiled and registered with the
`fix_binary` flag
Use the [`tonistiigi/binfmt`](https://github.com/tonistiigi/binfmt) image to
install QEMU and register the executable types on the host with a single
command:
```console
$ docker run --privileged --rm tonistiigi/binfmt --install all
```
This installs the QEMU binaries and registers them with
[`binfmt_misc`](https://en.wikipedia.org/wiki/Binfmt_misc), enabling QEMU to
execute non-native file formats for emulation.
Once QEMU is installed and the executable types are registered on the host OS,