I’ve been using BuildKit for a quite a while and can confirm that it’s a great tool for building Docker images. It’s quick, reliable and comes with Docker starting from version 18.09.
I wrote two articles describing my experiments with BuildKit, one about low level set up for building cross-platform images by using emulation, BuildKit builder, and buildctl directly. And another one about using BuildKit as well but without an emulator and relying on docker build
command. The solution described in those articles is not ideal since you have to create platform-specific images one by one, push them to a Docker registry, create a multi-platform manifest, then push it as well, and, finally, delete the platform-specific tags.
Luckily enough, Docker 19.03 has buildx included in the package. Long story short, using buildx
and BuildKit you can not only build images for multiple platforms in parallel but also push multi-platform manifests alongside the images built to Docker Registry!
The workflow:
- Get the latest Docker (19.03 or later) and enable the experimental features.
- Log in to your Docker registry
docker login
. - Create a
docker-container
driver and set it to be the current builder.
docker buildx create --use
- Build and push multi-platform images and the manifest.
docker buildx build \
--progress=plain \
--platform="linux/amd64,linux/arm64,linux/ppc64le,linux/s390x,linux/386,linux/arm/v7,linux/arm/v6" \
--tag foo/bar:1 --tag foo/bar:1.1 --tag foo/bar:1.1.1 -tag foo/bar:latest \
--push .
NOTE: --progress=plain
is used to avoid CI logs pollution.
This is basically it.
Please note that if you are not using RUN commands in the target platform part of your Docker file, you don’t need to register format recognizers. The emulator is not involved in such builds. But if you do, then make sure you do it before creating a BuildKit builder:
sudo docker run --privileged linuxkit/binfmt:v0.7
P.S. I created a Docker image with some bash scripts for simplifying multi-platform builds. Using those scripts you can update Docker, build and push a multi-platform image tagging it using a semantic tag, and push README file to Docker Hub. An example of using the scripts you can find here.