Using Docker Buildx to Build Images for Multiple System Architectures

[ad_1]
Docker Buildx is a docker CLI plug-in that extends the docker command to support the functionality provided by Moby BuildKit. Provides the same user experience as docker build and adds many new features.
BuildKit is a next-generation image building component with many main features. This article mainly uses its feature of compiling multiple system architectures.
URL:https://github.com/moby/buildkit
It should be noted that this feature is only available for Docker v19.03+.
This article will explain how to use Buildx to build images for various system architectures.
Before you start, you have already installed 64-bit Docker under Linux system (major distributions) by default.
At the time of writing this article, the latest version number of Docker is 19.03.13.
$ docker version
Client: Docker Engine - Community Version: 19.03.13 API version: 1.40 Go version: go1.13.15 Git commit: 4484c46d9d Built: Wed Sep 16 17:03:45 2020 OS/Arch: linux/amd64 Experimental: true Server: Docker Engine - Community Engine: Version: 19.03.13 API version: 1.40 (minimum version 1.12) Go version: go1.13.15 Git commit: 4484c46d9d Built: Wed Sep 16 17:02:21 2020 OS/Arch: linux/amd64 Experimental: false containerd: Version: 1.3.7 GitCommit: 8fba4e9a7d01810a393d5d25a3621dc101981175 runc: Version: 1.0.0-rc10 GitCommit: dc9208a3303feef5b3839f4323d9beb36df0a9dd docker-init: Version: 0.18.0 GitCommit: fec3683
1. Enable Buildx
The buildx command is an experimental feature, so you need to enable it first.
In the content returned by checking the Docker version above, ifExperimental: true
The words indicate that this feature has been turned on. This next step can be omitted.
Edit the ~/.docker/config.json file and add the following content (the following demonstration is applicable when the .docker directory does not exist in advance)
$ mkdir ~/.docker $ cat > ~/.docker/config.json <<EOF { "experimental": "enabled" } EOF
Under Linux/macOS or by setting environment variables (not recommended):
$ export DOCKER_CLI_EXPERIMENTAL=enabled
2. Create a new builder instance
Available in Docker 19.03+ version docker buildx build
The command uses BuildKit to build the image.This command supports --platform
Parameters can simultaneously build Docker images that support multiple system architectures, greatly simplifying the construction steps.
Since Docker's default builder instance does not support specifying multiple --platform
we must first create a new builder instance.
$ docker buildx create --name mybuilder --driver docker-container
Returns the new builder instance name, which is “mybuilder”
mybuilder
Use the newly created builder instance
$ docker buildx use mybuilder
View existing builder instances
$ docker buildx ls NAME/NODE DRIVER/ENDPOINT STATUS PLATFORMS mybuilder * docker-container mybuilder0 unix:///var/run/docker.sock inactive default docker default default running linux/amd64, linux/386
Docker does not support arm architecture images under the Linux/amd64 system architecture, so we can run a new container (emulator) to support this feature. Docker desktop version does not require this setting.
method one:
$ docker run --rm --privileged docker/binfmt:a7996909642ee92942dcd6cff44b9b95f08dad64
Note: docker/binfmt can refer to the URL:https://hub.docker.com/r/docker/binfmt/tags Get the latest image
Method two (recommended):
$ docker run --rm --privileged tonistiigi/binfmt --install all
Go to the reference website:https://hub.docker.com/r/tonistiigi/binfmt Get the latest image.Currently (updated on 2021/04/20) Qemu version: 5.0.0
3. Create a new Dockerfile file
To build images for multiple system architectures, a supporting Dockerfile is also required.
Below is a sample Dockerfile.
Reference links:https://github.com/teddysun/across/blob/master/docker/kms/Dockerfile.architecture
The content of the Dockerfile file is as follows:
FROM --platform=$TARGETPLATFORM alpine:latest AS builder WORKDIR /root RUN apk add --no-cache git make build-base && \ git clone --branch master --single-branch https://github.com/Wind4/vlmcsd.git && \ cd vlmcsd/ && \ make FROM --platform=$TARGETPLATFORM alpine:latest LABEL maintainer="Teddysun <(email protected)>" COPY --from=builder /root/vlmcsd/bin/vlmcsd /usr/bin/vlmcsd EXPOSE 1688 CMD ( "vlmcsd", "-D", "-e" )
$TARGETPLATFORM
is a built-in variable, represented by --platform
parameter to specify its value.
Since it is based on mirror of alpineto make, and alpine It supports the following 7 system architectures, so the images we make also support these 7 system architectures.
linux/amd64, linux/arm/v6, linux/arm/v7, linux/arm64, linux/386, linux/ppc64le, linux/s390x
A more friendly schema name is as follows:
amd64, arm32v6, arm32v7, arm64v8, i386, ppc64le, s390x
Here is a comment interspersed.
After a brief statistics, ARM’s system architecture has the following abbreviations:
arm64, armv8l, arm64v8, aarch64 arm, arm32, arm32v7, armv7, armv7l, armhf arm32v6, armv6, armv6l, arm32v5, armv5, armv5l, armel, aarch32
After reading this, do you want to hit someone?
Comparing Intel and AMD is much simpler:
x86, 386, i386, i686 x86_64, x64, amd64
4. Build the image
Let’s build one locally first.
git clone the sample Dockerfile just now and enter its directory
$ cd ~ && git clone https://github.com/teddysun/across.git && cd across/docker/kms/
Build images locally that support 7 platforms
$ docker buildx build --platform linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x,linux/386 -t teddysun/kms -o type=local,dest=.docker -f ./Dockerfile.architecture .
For the specific parameter meanings of docker buildx build, please refer to the official document below
https://docs.docker.com/engine/reference/commandline/buildx_build/
After completing the above step, you actually place the built image in the local path.
At this point let's take a look at the existing builder instances.
$ docker buildx ls NAME/NODE DRIVER/ENDPOINT STATUS PLATFORMS mybuilder * docker-container mybuilder0 unix:///var/run/docker.sock running linux/amd64, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6 default docker default default running linux/amd64, linux/386
You will find that there are 8 supported architectures under mybuilder (riscv64 is not currently available, but it is supported).
At this time, check the running status of docker image and you will find that there is a file called buildx_buildkit_mybuilder0
container is running.
This was automatically created when building locally just now. Remember not to stop it or delete it.
$ docker ps -as CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES SIZE be753fa16090 moby/buildkit:buildx-stable-1 "buildkitd" 15 minutes ago Up 15 minutes buildx_buildkit_mybuilder0 0B (virtual 78.6MB)
Then build a multi-system architecture image and push the built image to the Docker warehouse (that is, hub.docker.com)。
Before this operation, you need to register an account in advance (the demonstration process is omitted) and log in.
The login command is as follows:
$ docker login
Enter your username and password to log in.
Note that in the following demonstrated command, the tag is preceded by my user name. teddysun
if you want to make your own mirror, please replace it with your own username.
use --push
The image built with parameters is pushed to the Docker warehouse.
At this time, it is still in the ~/across/docker/kms directory just now, and the file Dockerfile.architecture
It is prepared for multi-system architecture construction.
The command is as follows:
$ docker buildx build --platform linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x -t teddysun/kms --push -f ./Dockerfile.architecture .
After the command is executed successfully, you will see the image you uploaded in Docker Hub. An example diagram is as follows:
5.
When making a Docker image with a multi-system architecture, it is recommended to use a VPS with a strong CPU or multi-core to build it, otherwise it will be very time-consuming.