mirror of https://github.com/docker/docs.git
Merge pull request #20051 from dvdksn/build-simplify-multiplatform
build: simplify multi-platform docs
This commit is contained in:
commit
0025e4d9bf
|
@ -9,36 +9,55 @@ aliases:
|
||||||
- /mackit/multi-arch/
|
- /mackit/multi-arch/
|
||||||
---
|
---
|
||||||
|
|
||||||
Docker images can support multiple platforms, which means that a single image
|
A multi-platform image refers to a single image that includes variants for
|
||||||
may contain variants for different architectures, and sometimes for different
|
multiple different architectures and, in some cases, different operating
|
||||||
operating systems, such as Windows.
|
systems, like Windows. This means that whether you are using an ARM-based
|
||||||
|
system or an x86 machine, Docker automatically detects and selects the
|
||||||
|
appropriate variant for your hosts's operating system and architecture.
|
||||||
|
|
||||||
When you run an image with multi-platform support, Docker automatically selects
|
Many of the Docker Official Images available on Docker Hub support various
|
||||||
the image that matches your OS and architecture.
|
architectures. For instance, the `busybox` image includes support for these
|
||||||
|
platforms:
|
||||||
|
|
||||||
Most of the Docker Official Images on Docker Hub provide a [variety of architectures](https://github.com/docker-library/official-images#architectures-other-than-amd64).
|
- x86-64 (`linux/amd64`, `linux/i386`)
|
||||||
For example, the `busybox` image supports `amd64`, `arm32v5`, `arm32v6`,
|
- ARM architectures (`linux/arm/v5`, `linux/arm/v6`, `linux/arm/v7`, `linux/arm64`)
|
||||||
`arm32v7`, `arm64v8`, `i386`, `ppc64le`, and `s390x`. When running this image
|
- PowerPC and IBM Z (`linux/ppc64le`, `linux/s390x`)
|
||||||
on an `x86_64` / `amd64` machine, the `amd64` variant is pulled and run.
|
|
||||||
|
On an x86 machine, Docker will automatically use the `linux/amd64` variant
|
||||||
|
when you run a container or invoke a build.
|
||||||
|
|
||||||
|
Most Docker images use the `linux/` OS prefix to indicate they are Linux-based.
|
||||||
|
While Docker Desktop on macOS or Windows typically runs Linux containers using
|
||||||
|
a Linux VM, Docker also supports Windows containers if you're operating in
|
||||||
|
Windows container mode.
|
||||||
|
|
||||||
## Building multi-platform images
|
## Building multi-platform images
|
||||||
|
|
||||||
When you invoke a build, you can set the `--platform` flag to specify the target
|
When triggering a build, use the `--platform` flag to define the target
|
||||||
platform for the build output. For example, `linux/amd64`, `linux/arm64`, or
|
platforms for the build output, such as `linux/amd64` and `linux/arm64`:
|
||||||
`darwin/amd64`.
|
|
||||||
|
|
||||||
By default, you can only build for a single platform at a time. If you want to
|
```console
|
||||||
build for multiple platforms at once, you can:
|
$ docker build --platform linux/amd64,linux/arm64 .
|
||||||
|
```
|
||||||
|
|
||||||
- Create a new builder that uses the [`docker-container` driver](../drivers/docker-container.md)
|
By default, Docker can build for only one platform at a time.
|
||||||
- Turn on the [containerd snapshotter storage](../../desktop/containerd/index.md)
|
To build for multiple platforms concurrently, you can:
|
||||||
|
|
||||||
|
- **Enable the containerd image store**:
|
||||||
|
The default image store in Docker Engine doesn't support multi-platform images.
|
||||||
|
The containerd image store does, and lets you create multi-platform images using the default builder.
|
||||||
|
Refer to the [containerd in Docker Desktop documentation](../../desktop/containerd.md).
|
||||||
|
|
||||||
|
- **Create a custom builder**:
|
||||||
|
Initialize a [builder](../builders/_index.md) that uses the `docker-container` driver, which supports multi-platform builds.
|
||||||
|
For more details, see the [`docker-container` driver documentation](../drivers/docker-container.md).
|
||||||
|
|
||||||
## Strategies
|
## Strategies
|
||||||
|
|
||||||
You can build multi-platform images using three different strategies,
|
You can build multi-platform images using three different strategies,
|
||||||
depending on your use case:
|
depending on your use case:
|
||||||
|
|
||||||
1. Using the [QEMU emulation](#qemu) support in the kernel
|
1. Using emulation, via [QEMU](#qemu) support in the Linux kernel
|
||||||
2. Building on a single builder backed by
|
2. Building on a single builder backed by
|
||||||
[multiple nodes of different architectures](#multiple-native-nodes).
|
[multiple nodes of different architectures](#multiple-native-nodes).
|
||||||
3. Using a stage in your Dockerfile to [cross-compile](#cross-compilation) to
|
3. Using a stage in your Dockerfile to [cross-compile](#cross-compilation) to
|
||||||
|
@ -63,26 +82,30 @@ loads it through a binary registered in the `binfmt_misc` handler.
|
||||||
|
|
||||||
#### Support on Docker Desktop
|
#### Support on Docker Desktop
|
||||||
|
|
||||||
[Docker Desktop](../../desktop/index.md) provides `binfmt_misc`
|
[Docker Desktop](../../desktop/_index.md) provides support for running and
|
||||||
multi-architecture support, which means you can run containers for different
|
building multi-platform images under emulation by default, which means you can
|
||||||
Linux architectures such as `arm`, `mips`, `ppc64le`, and even `s390x`.
|
run containers for different Linux architectures such as `arm`, `mips`,
|
||||||
|
`ppc64le`, and even `s390x`.
|
||||||
|
|
||||||
This doesn't require any special configuration in the container itself as it
|
This doesn't require any special configuration in the container itself as it
|
||||||
uses [qemu-static](https://wiki.qemu.org/Main_Page)
|
uses QEMU bundled within the Docker Desktop VM. Because of this, you can run
|
||||||
from the Docker Desktop VM. Because of this, you can run an ARM container,
|
containers of non-native architectures like the `arm32v7` or `ppc64le`
|
||||||
like the `arm32v7` or `ppc64le` variants of the busybox image.
|
automatically.
|
||||||
|
|
||||||
#### QEMU without Docker Desktop
|
#### QEMU without Docker Desktop
|
||||||
|
|
||||||
For QEMU binaries registered with `binfmt_misc` on the host OS to work
|
If you're running Docker Engine on Linux, without Docker Desktop, you must
|
||||||
transparently inside containers, they must be statically compiled and
|
install statically compiled QEMU binaries and register them with
|
||||||
registered with the `fix_binary` flag. This requires a kernel version 4.8 or
|
[`binfmt_misc`](https://en.wikipedia.org/wiki/Binfmt_misc). This enables QEMU
|
||||||
later, and `binfmt-support` version 2.1.7 or later.
|
to execute non-native file formats for emulation. The QEMU binaries must be
|
||||||
|
statically compiled and registered with the `fix_binary` flag. This requires a
|
||||||
|
kernel version 4.8 or later, and `binfmt-support` version 2.1.7 or later.
|
||||||
|
|
||||||
You can verify your registration by checking if `F` is among the flags in
|
Once QEMU is installed and the executable types are registered on the host OS,
|
||||||
`/proc/sys/fs/binfmt_misc/qemu-*`. While Docker Desktop comes preconfigured
|
they work transparently inside containers. You can verify your registration by
|
||||||
with `binfmt_misc` support for additional platforms, for other installations it
|
checking if `F` is among the flags in `/proc/sys/fs/binfmt_misc/qemu-*`. While
|
||||||
likely needs to be installed using
|
Docker Desktop comes preconfigured with `binfmt_misc` support for additional
|
||||||
|
platforms, for other installations it likely needs to be installed using
|
||||||
[`tonistiigi/binfmt`](https://github.com/tonistiigi/binfmt) image:
|
[`tonistiigi/binfmt`](https://github.com/tonistiigi/binfmt) image:
|
||||||
|
|
||||||
```console
|
```console
|
||||||
|
@ -109,11 +132,11 @@ $ docker buildx build --platform linux/amd64,linux/arm64 .
|
||||||
|
|
||||||
While this approach has advantages over emulation, managing multi-node builders
|
While this approach has advantages over emulation, managing multi-node builders
|
||||||
introduces some overhead of setting up and managing builder clusters.
|
introduces some overhead of setting up and managing builder clusters.
|
||||||
Alternatively, you can use [Docker Build Cloud](/build/cloud/), a service that
|
Alternatively, you can use Docker Build Cloud, a service that provides managed
|
||||||
provides managed multi-node builders on Docker's infrastructure. With Docker
|
multi-node builders on Docker's infrastructure. With Docker Build Cloud, you
|
||||||
Build Cloud, you get native multi-platform Arm and X86-64 builders without the
|
get native multi-platform ARM and X86 builders without the burden of
|
||||||
burden of maintaining them. Using cloud builders also provides additional
|
maintaining them. Using cloud builders also provides additional benefits, such
|
||||||
benefits, such as a shared build cache.
|
as a shared build cache.
|
||||||
|
|
||||||
After signing up for Docker Build Cloud, add the builder to your local
|
After signing up for Docker Build Cloud, add the builder to your local
|
||||||
environment and start building.
|
environment and start building.
|
||||||
|
@ -121,20 +144,29 @@ environment and start building.
|
||||||
```console
|
```console
|
||||||
$ docker buildx create --driver cloud <ORG>/<BUILDER_NAME>
|
$ docker buildx create --driver cloud <ORG>/<BUILDER_NAME>
|
||||||
cloud-<ORG>-<BUILDER_NAME>
|
cloud-<ORG>-<BUILDER_NAME>
|
||||||
$ docker buildx build --builder cloud-<ORG>-<BUILDER_NAME> \
|
$ docker build \
|
||||||
|
--builder cloud-<ORG>-<BUILDER_NAME> \
|
||||||
--platform linux/amd64,linux/arm64,linux/arm/v7 \
|
--platform linux/amd64,linux/arm64,linux/arm/v7 \
|
||||||
--tag <IMAGE_NAME> \
|
--tag <IMAGE_NAME> \
|
||||||
--push .
|
--push .
|
||||||
```
|
```
|
||||||
|
|
||||||
|
For more information, see [Docker Build Cloud](../cloud/_index.md).
|
||||||
|
|
||||||
### Cross-compilation
|
### Cross-compilation
|
||||||
|
|
||||||
Depending on your project, if the programming language you use has good support
|
Depending on your project, if the programming language you use has good support
|
||||||
for cross-compilation, multi-stage builds in Dockerfiles can be effectively
|
for cross-compilation, you can leverage multi-stage builds to build binaries
|
||||||
used to build binaries for target platforms using the native architecture of
|
for target platforms from the native architecture of the builder. Special build
|
||||||
the build node. Build arguments such as `BUILDPLATFORM` and `TARGETPLATFORM`
|
arguments, such as `BUILDPLATFORM` and `TARGETPLATFORM`, are automatically
|
||||||
are automatically available for use in your Dockerfile, and can be leveraged by
|
available for use in your Dockerfile.
|
||||||
the processes running as part of your build.
|
|
||||||
|
In the following example, the `FROM` instruction is pinned to the native
|
||||||
|
platform of the builder (using the `--platform=$BUILDPLATFORM` option) to
|
||||||
|
prevent emulation from kicking in. Then the pre-defined `$BUILDPLATFORM` and
|
||||||
|
`$TARGETPLATFORM` build arguments are interpolated in a `RUN` instruction. In
|
||||||
|
this case, the values are just printed to stdout with `echo`, but this
|
||||||
|
illustrates how you would pass them to the compiler for cross-compilation.
|
||||||
|
|
||||||
```dockerfile
|
```dockerfile
|
||||||
# syntax=docker/dockerfile:1
|
# syntax=docker/dockerfile:1
|
||||||
|
@ -159,7 +191,7 @@ default * docker
|
||||||
```
|
```
|
||||||
|
|
||||||
This displays the default builtin driver, that uses the BuildKit server
|
This displays the default builtin driver, that uses the BuildKit server
|
||||||
components built directly into the docker engine, also known as the [`docker` driver](../drivers/docker.md).
|
components built directly into the Docker Engine, also known as the [`docker` driver](../drivers/docker.md).
|
||||||
|
|
||||||
Create a new builder using the [`docker-container` driver](../drivers/docker-container.md)
|
Create a new builder using the [`docker-container` driver](../drivers/docker-container.md)
|
||||||
which gives you access to more complex features like multi-platform builds
|
which gives you access to more complex features like multi-platform builds
|
||||||
|
@ -170,7 +202,7 @@ default `docker` driver:
|
||||||
$ docker buildx create --name mybuilder --bootstrap --use
|
$ docker buildx create --name mybuilder --bootstrap --use
|
||||||
```
|
```
|
||||||
|
|
||||||
Now listing the existing builders again, we can see our new builder is
|
Now listing the existing builders again, you can see that the new builder is
|
||||||
registered:
|
registered:
|
||||||
|
|
||||||
```console
|
```console
|
||||||
|
@ -230,8 +262,8 @@ $ docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 -t <userna
|
||||||
>
|
>
|
||||||
> * `<username>` must be a valid Docker ID and `<image>` and valid repository on
|
> * `<username>` must be a valid Docker ID and `<image>` and valid repository on
|
||||||
> Docker Hub.
|
> Docker Hub.
|
||||||
> * The `--platform` flag informs buildx to create Linux images for AMD 64-bit,
|
> * The `--platform` flag informs buildx to create Linux images for x86 64-bit,
|
||||||
> Arm 64-bit, and Armv7 architectures.
|
> ARM 64-bit, and ARMv7 architectures.
|
||||||
> * The `--push` flag generates a multi-arch manifest and pushes all the images
|
> * The `--push` flag generates a multi-arch manifest and pushes all the images
|
||||||
> to Docker Hub.
|
> to Docker Hub.
|
||||||
|
|
||||||
|
@ -260,8 +292,8 @@ Manifests:
|
||||||
The image is now available on Docker Hub with the tag `<username>/<image>:latest`.
|
The image is now available on Docker Hub with the tag `<username>/<image>:latest`.
|
||||||
You can use this image to run a container on Intel laptops, Amazon EC2 Graviton
|
You can use this image to run a container on Intel laptops, Amazon EC2 Graviton
|
||||||
instances, Raspberry Pis, and on other architectures. Docker pulls the correct
|
instances, Raspberry Pis, and on other architectures. Docker pulls the correct
|
||||||
image for the current architecture, so Raspberry PIs run the 32-bit Arm version
|
image for the current architecture, so Raspberry PIs run the 32-bit ARM version
|
||||||
and EC2 Graviton instances run 64-bit Arm.
|
and EC2 Graviton instances run 64-bit ARM.
|
||||||
|
|
||||||
The digest identifies a fully qualified image variant. You can also run images
|
The digest identifies a fully qualified image variant. You can also run images
|
||||||
targeted for a different architecture on Docker Desktop. For example, when
|
targeted for a different architecture on Docker Desktop. For example, when
|
||||||
|
@ -277,5 +309,5 @@ $ docker run --rm docker.io/<username>/<image>:latest@sha256:723c22f366ae44e419d
|
||||||
armv7l
|
armv7l
|
||||||
```
|
```
|
||||||
|
|
||||||
In the above example, `uname -m` returns `aarch64` and `armv7l` as expected,
|
In the previous example, `uname -m` returns `aarch64` and `armv7l` as expected,
|
||||||
even when running the commands on a native macOS or Windows developer machine.
|
even when running the commands on a native macOS or Windows developer machine.
|
||||||
|
|
Loading…
Reference in New Issue