Compilación cruzada en Docker (PeerTube)

En esta entrada explicaremos como hacer una compilación cruzada (crosscompiling) de la imagen de Docker de PeerTube en una máquina con arquitectura amd64 para arm64 (Raspberry Pi4). Consume un poco más de recursos en la máquina nativa por la emulación, pero merece la pena así no perdemos tiempo ni proceso en preparar las imágenes desde la Pi, esto podemos hacerlo con cualquier imagen siempre que existan las imágenes que use de base el Dockerfile para arquitectura arm64 (aarch64)

Para realizar la compilación cruzada entre arquitecturas usaremos Docker y QEMU, tenemos que tenerlos instalados en el sistema, ejecutamos la imagen de QEMU para instalar los binarios de las distintas arquitecturas como se indica en esta entrada

$ docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
Setting /usr/bin/qemu-alpha-static as binfmt interpreter for alpha
Setting /usr/bin/qemu-arm-static as binfmt interpreter for arm
Setting /usr/bin/qemu-armeb-static as binfmt interpreter for armeb
Setting /usr/bin/qemu-sparc-static as binfmt interpreter for sparc
Setting /usr/bin/qemu-sparc32plus-static as binfmt interpreter for sparc32plus
Setting /usr/bin/qemu-sparc64-static as binfmt interpreter for sparc64
Setting /usr/bin/qemu-ppc-static as binfmt interpreter for ppc
Setting /usr/bin/qemu-ppc64-static as binfmt interpreter for ppc64
Setting /usr/bin/qemu-ppc64le-static as binfmt interpreter for ppc64le
Setting /usr/bin/qemu-m68k-static as binfmt interpreter for m68k
Setting /usr/bin/qemu-mips-static as binfmt interpreter for mips
Setting /usr/bin/qemu-mipsel-static as binfmt interpreter for mipsel
Setting /usr/bin/qemu-mipsn32-static as binfmt interpreter for mipsn32
Setting /usr/bin/qemu-mipsn32el-static as binfmt interpreter for mipsn32el
Setting /usr/bin/qemu-mips64-static as binfmt interpreter for mips64
Setting /usr/bin/qemu-mips64el-static as binfmt interpreter for mips64el
Setting /usr/bin/qemu-sh4-static as binfmt interpreter for sh4
Setting /usr/bin/qemu-sh4eb-static as binfmt interpreter for sh4eb
Setting /usr/bin/qemu-s390x-static as binfmt interpreter for s390x
Setting /usr/bin/qemu-aarch64-static as binfmt interpreter for aarch64
Setting /usr/bin/qemu-aarch64_be-static as binfmt interpreter for aarch64_be
Setting /usr/bin/qemu-hppa-static as binfmt interpreter for hppa
Setting /usr/bin/qemu-riscv32-static as binfmt interpreter for riscv32
Setting /usr/bin/qemu-riscv64-static as binfmt interpreter for riscv64
Setting /usr/bin/qemu-xtensa-static as binfmt interpreter for xtensa
Setting /usr/bin/qemu-xtensaeb-static as binfmt interpreter for xtensaeb
Setting /usr/bin/qemu-microblaze-static as binfmt interpreter for microblaze
Setting /usr/bin/qemu-microblazeel-static as binfmt interpreter for microblazeel
Setting /usr/bin/qemu-or1k-static as binfmt interpreter for or1k

Clonamos el repositorio con el Dockerfile para generar la imagen

$ git clone https://github.com/Chocobozzz/PeerTube

Nos posicionamos en la carpeta y se lanza el comando docker con buildx indicando el tipo de plataforma a compilar, el nombre (tag) de la imagen que se generará y la ruta hasta el Dockerfile.buster

$ cd PeerTube
$ docker buildx build --platform arm64 -t peertube -f support/docker/production/Dockerfile.buster .
[+] Building 18.6s (5/13)                                                       
 => [1/9] FROM docker.io/library/node:12-buster-slim@sha256:05760af3b26da  8.0s
 => => resolve docker.io/library/node:12-buster-slim@sha256:05760af3b26da  0.0s
...

Una vez generada podemos exportarla para copiarla y poder instanciar el contenedor en la Raspberry Pi

$ docker image save -o peertube.tar peertube

La copiamos y ejecutamos

$ docker image import --platform arm64 peertube.tar peertube
$ docker images --format '{{.Repository}}'
peertube

Ya tenemos la imagen generada y cargada en el docker de la RaspberryPi, también podemos usar un registro local de Docker donde subir la imagen directamente y así poder descargarla desde la máquina, es otra opción

Saludos