Solución:
Resolví mi propio problema después de un poco de investigación … Primero, estaba cometiendo un error estúpido y segundo, estaba olvidando algo muy importante. Así es como solucioné mis problemas:
El error estúpido
Aunque especifiqué diferente Dockerfile
s para cada compilación automatizada, también tenía un build
gancho que estaba sobrescribiendo el docker build
comando y estaba por defecto en Dockerfile
para todas las compilaciones en lugar de elegir el archivo correcto.
Reparado build
archivo de gancho:
#!/bin/bash
docker build
--file "${DOCKERFILE_PATH}"
--build-arg BUILD_DATE="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
--build-arg VCS_REF="$(git rev-parse --short HEAD)"
--tag "$IMAGE_NAME"
.
La cosa importante
Como @JanGaraj mencionó en su respuesta, Docker Hub se ejecuta en amd64
por lo que no puede ejecutar binarios para otras arquitecturas. ¿Cómo se crean imágenes de varios arcos con las compilaciones automatizadas de Docker Hub? Con la ayuda de qemu-user-static
y más ganchos. Encontré la respuesta a este problema de GitHub, pero publicaré aquí la respuesta completa a mi caso de uso específico:
Mi árbol de proyecto de muestra:
.
├── Dockerfile
├── Dockerfile.aarch64
├── Dockerfile.armhf
└── hooks
├── build
├── post_checkout
└── pre_build
los post_checkout
archivo de gancho:
#!/bin/bash
BUILD_ARCH=$(echo "${DOCKERFILE_PATH}" | cut -d '.' -f 2)
[ "${BUILD_ARCH}" == "Dockerfile" ] &&
{ echo 'qemu-user-static: Download not required for current arch'; exit 0; }
QEMU_USER_STATIC_ARCH=$([ "${BUILD_ARCH}" == "armhf" ] && echo "${BUILD_ARCH::-2}" || echo "${BUILD_ARCH}")
QEMU_USER_STATIC_DOWNLOAD_URL="https://github.com/multiarch/qemu-user-static/releases/download"
QEMU_USER_STATIC_LATEST_TAG=$(curl -s https://api.github.com/repos/multiarch/qemu-user-static/tags
| grep 'name.*v[0-9]'
| head -n 1
| cut -d '"' -f 4)
curl -SL "${QEMU_USER_STATIC_DOWNLOAD_URL}/${QEMU_USER_STATIC_LATEST_TAG}/x86_64_qemu-${QEMU_USER_STATIC_ARCH}-static.tar.gz"
| tar xzv
los pre_build
archivo de gancho:
#!/bin/bash
BUILD_ARCH=$(echo "${DOCKERFILE_PATH}" | cut -d '.' -f 2)
[ "${BUILD_ARCH}" == "Dockerfile" ] &&
{ echo 'qemu-user-static: Registration not required for current arch'; exit 0; }
docker run --rm --privileged multiarch/qemu-user-static:register --reset
los Dockerfile
expediente:
FROM amd64/alpine:3.8
(...)
los Dockerfile.aarch64
expediente:
FROM arm64v8/alpine:3.8
COPY qemu-aarch64-static /usr/bin/
(...)
los Dockerfile.armhf
expediente:
FROM arm32v6/alpine:3.8
COPY qemu-arm-static /usr/bin/
(...)
¡Eso es todo!
Imagen de Docker golang:1.11-alpine3.8
es una imagen multiarca. Lista de arquitecturas disponibles:
$ docker run --rm mplatform/mquery golang:1.11-alpine3.8
Image: golang:1.11-alpine3.8
* Manifest List: Yes
* Supported platforms:
- linux/amd64
- linux/arm/v6
- linux/arm64
- linux/386
- linux/ppc64le
- linux/s390x
Entonces, primer problema: plataforma arm32/v7
no está disponible para esta imagen de Docker. Segundo problema: el demonio de Docker extraerá la imagen de la plataforma, que es la misma que la plataforma del demonio de Docker. Supongo que Docker Hub se ejecuta en amd64
, entonces elegirá amd64
.
Mi recomendación: compile binario enlazado estático + multiplataforma Go (GOARCH=arm GOARM=7
) + uso SCRATCH
imagen base y podrás crear arm7
también con amd64
Estibador.
Hoy en día, también puede usar docker buildx para compilar para diferentes arquitecturas sin tener que mantener un Dockerfile separado para cada una. Creación de imágenes de Docker de arquitectura múltiple con Buildx tiene una descripción de cómo funciona. Básicamente, tu
- Registre su simulador QEMU en binfmt_misc en el host con el indicador fix-binary para que pueda ejecutarse en el contenedor sin tener que copiarlo en el sistema de archivos del contenedor.
- usar
docker buildx build --platform linux/arm/v7 ...
para indicarle al constructor que construya para una arquitectura diferente a la de su host de compilación