docker buildx post
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
0b5b4d243b
commit
936d049552
|
|
@ -0,0 +1,100 @@
|
||||||
|
---
|
||||||
|
title: "Using Docker buildx for native multiarch builds."
|
||||||
|
date: 2022-12-24T05:07:00+02:00
|
||||||
|
draft: false
|
||||||
|
---
|
||||||
|
|
||||||
|
## TL;DR
|
||||||
|
|
||||||
|
I wanted to build multiarch images using multiple machines with different architectures instead of QEMU.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# add some amd64 machine that has docker
|
||||||
|
docker context create bob --docker "host=ssh://bob@10.0.0.2"
|
||||||
|
# create a buildx builder with your local machine added to it
|
||||||
|
docker buildx create \
|
||||||
|
--name multiarch --node arm64 \
|
||||||
|
--platform linux/arm64/v8 \
|
||||||
|
default
|
||||||
|
# add the amd64 machine to it
|
||||||
|
docker buildx create --append \
|
||||||
|
--name multiarch --node amd64 \
|
||||||
|
--platform linux/amd64,linux/amd64/v2,linux/386\
|
||||||
|
bob
|
||||||
|
# build & push your image
|
||||||
|
docker buildx build \
|
||||||
|
--builder multiarch \
|
||||||
|
--platform linux/amd64,linux/arm64/v8 \
|
||||||
|
--push --tag username/imagename .
|
||||||
|
|
||||||
|
# the amd64 image will be build natively on the amd64 machine,
|
||||||
|
# the arm64 machine will be build natively on the arm64 machine
|
||||||
|
```
|
||||||
|
|
||||||
|
## Actual post
|
||||||
|
|
||||||
|
I wanted to build a multiarch image for `linux/arm64/v8` and `linux/amd64`, however the `x86` builds were really slow when running through QEMU on my _Apple Silicon_ laptop. Turns out, you can tell Docker to use another machine (which happens to be `x86_64`), to build the `linux/amd64` images, and use the local Docker Desktop instance for the ARM stuff.
|
||||||
|
|
||||||
|
Here's how:
|
||||||
|
|
||||||
|
1. Set up Docker on a machine (or many machines) that supports the architecture(s) you want to build for. Make sure you can SSH into it without using passwords (use SSH keys, and maybe ssh-agent if keys don't work on their own).
|
||||||
|
|
||||||
|
Also, the user you're SSH-ing into needs to be able to access Docker.
|
||||||
|
|
||||||
|
2. Create a _Docker context_ for the remote machine.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker context create <context_name> --docker "host=ssh://<USER>@<HOST>:<PORT>"
|
||||||
|
```
|
||||||
|
|
||||||
|
`<USER>@` can be omitted - your local username will be used. `:<PORT>` can also be omitted if it's `22`.
|
||||||
|
|
||||||
|
Let's say we have an `amd64` host on ip `10.0.0.2`, and we want to call it bob (the builder).
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker context create bob --docker "host=ssh://bob@10.0.0.2"
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Create a buildx builder for your local computer. In this case, my local machine supports linux/arm64/v8 natively, but it also can build amd64 images through qemu, so I explicitly set `--platform` to just `linux/arm64/v8`. I might also add `linux/arm/v7` for images meant to run on something like a Raspberry Pi here, because even though it will still run via QEMU, I don't have anything better to build for `armv7` anyway. (it's comma separated)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker buildx create \
|
||||||
|
--name multiarch --node arm64 \
|
||||||
|
--platform linux/arm64/v8 \
|
||||||
|
default
|
||||||
|
```
|
||||||
|
|
||||||
|
`multiarch` will be the name of our builder, `--node` is the name for the node we're adding to the builder (it doesn't have to contain the architecture, it can be anything, only the `--platform` value is taken into consideration by Docker).
|
||||||
|
|
||||||
|
`default` is the name of the default context, which usually is your local machine. If not, replace it with whatever you use.
|
||||||
|
|
||||||
|
4. Now, the fun part - add additional nodes for other architectures! In our example, we want to add `bob` which can build `linux/amd64` images natively.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker buildx create --append \
|
||||||
|
--name multiarch --node amd64 bob
|
||||||
|
```
|
||||||
|
|
||||||
|
Notice the `--append` - it tells Docker to add the node to an existing builder.
|
||||||
|
|
||||||
|
I've omitted `--platform` here, because in my case, `bob` only supports x86 anyways, so I don't have to limit it artificially. This was different for the local node, as Docker Desktop on MacOS comes with cross-platform build support preconfigured.
|
||||||
|
|
||||||
|
5. Set the builder as default (optional, you can use `--builder multiarch` for `docker buildx build` to set the builder manually)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker buildx use multiarch
|
||||||
|
```
|
||||||
|
|
||||||
|
6. Finally, you can build your images:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker buildx build \
|
||||||
|
--platform linux/amd64,linux/arm64/v8 \
|
||||||
|
--push --tag username/imagename .
|
||||||
|
```
|
||||||
|
|
||||||
|
Unfortunately, it's not yet possible to load multiarch images into your local Docker daemon, which means you're gonna have to tag and `--push` to the Docker registry.
|
||||||
|
|
||||||
|
You can still use `--load` instead of `--push` (to load into your local daemon) if you only specify a single `--platform`. Idk, might be useful for testing or something.
|
||||||
|
|
||||||
|
Enjoy.
|
||||||
|
|
@ -25,6 +25,10 @@ h2,h3,h4,h5 {
|
||||||
padding-bottom: .2em;
|
padding-bottom: .2em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
line-height: 1.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
header a {
|
header a {
|
||||||
color: #fdf6ff;
|
color: #fdf6ff;
|
||||||
|
|
@ -47,6 +51,7 @@ header > .icons > a {
|
||||||
|
|
||||||
#content {
|
#content {
|
||||||
margin-top: 3em;
|
margin-top: 3em;
|
||||||
|
line-height: 1.4em;
|
||||||
}
|
}
|
||||||
|
|
||||||
#homepage {
|
#homepage {
|
||||||
|
|
@ -197,16 +202,23 @@ ul.projectUpdateList {
|
||||||
font-size: 0.9em;
|
font-size: 0.9em;
|
||||||
}
|
}
|
||||||
|
|
||||||
pre,
|
|
||||||
.postList .timestamp {
|
.postList .timestamp {
|
||||||
font-family: 'Source Code Pro', monospace;
|
font-family: 'Source Code Pro', monospace;
|
||||||
font-weight: 200;
|
font-weight: 200;
|
||||||
}
|
}
|
||||||
|
|
||||||
pre {
|
.highlight {
|
||||||
font-size: 1.2em;
|
overflow-x: auto;
|
||||||
|
background-color: #272822;
|
||||||
|
margin-bottom: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
box-sizing: bounding-box;
|
||||||
|
line-height: 1.2;
|
||||||
|
font-size: 1.2em;
|
||||||
|
margin: 1em;
|
||||||
|
}
|
||||||
.seeAll {
|
.seeAll {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
padding-right: .5em;
|
padding-right: .5em;
|
||||||
|
|
@ -219,3 +231,7 @@ pre {
|
||||||
.project h3 {
|
.project h3 {
|
||||||
font-size: 1.2em;
|
font-size: 1.2em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ol > li {
|
||||||
|
margin-bottom: 2em;
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue