Image multi-architectures

Il n’y a pas que des puces Intel dans les ordinateurs
Aujourd’hui, nous ne pouvons pas ignorer les ordinateurs avec des architectures autres que amd64 (Intel). Le Raspberry Pi est un mini-ordinateur très populaire et il fonctionne avec un microprocesseur ARM. Tous les nouveaux Macbooks sont maintenant livrés avec un processeur basé sur la technologie ARM. Bien que ces Macs peuvent faire tourner des images Docker faites pour amd64 grâce à un émulateur, ça reste une solution peu performante.
Nous allons donc modifier notre projet pour que le runner produise également une image ARM.
Modifiez le fichier “.gitlab-ci.yml” en y ajoutant la ligne 35 avec l’option --opt platform=linux/amd64,linux/arm64 :
| .gitlab-ci.yml | |
|---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | |
Faites un commit puis in push et observez le résultat du pipeline_dans l’interface web de GitHub. Notez que le _runner prend plus de temps pour construire les images, car maintenant c’est lui qui doit émuler le processeur ARM. Après environ 3 minutes le résultat devrait être disponible dans le registry de GitLab.
Téléchargez la nouvelle image et refaites un essai :
docker pull registry.forge.hefr.ch/<NAMESPACE>/<REPOSITORY>:latest
docker run --rm registry.forge.hefr.ch/<NAMESPACE>/<REPOSITORY>:latest
et si vous avez une machine avec un processeur ARM, vous verrez la bonne architecture et pas de message de type warning :
Hello DevOps!
Go version: go1.25.0
Architecture: arm64
OS: linux
Si votre machine est capable de faire tourner des images pour les deux architectures, vous pouvez aussi faire tourner l’image pour les deux architectures et observer le résultat :
docker run --platform=linux/amd64 --rm registry.forge.hefr.ch/<NAMESPACE>/<REPOSITORY>:latest
docker run --platform=linux/arm64 --rm registry.forge.hefr.ch/<NAMESPACE>/<REPOSITORY>:latest
Notez que l’interface web de Gitlab ne montre pas les différentes architectures disponibles pour une image. Il y a actuellement un epic ouvert pour addresser ce problème:

En attendant, vous pouvez vérifier les différentes architectures disponibles pour une image avec la commande suivante :
docker manifest inspect <NAMESPACE>/<REPOSITORY>:latest
Vous devriez obtenir quelque chose comme ça :
{
"schemaVersion": 2,
...
"manifests": [
{
...
"platform": {
"architecture": "amd64",
"os": "linux"
}
},
{
...
"platform": {
"architecture": "arm64",
"os": "linux"
}
}
]
}
Publication de l’image dans le DockerHub
Jusqu’à maintenant, nous avons publié les images dans le registry de GitLab. Mais ce n’est pas la seule option et vous pouvez publier votre image dans d’autres registries publiques tels que :
- Docker Hub
- Canister.io
- GitHub
- AWS Container Registry
- Google Container Registry
Docker Hub est le plus populaire et nous allons y publier notre image.
Précédement, vous avez déjà défini les variables $DOCKER_HUB_USER et $DOCKER_HUB_TOKEN
et le token que vous avez généré vous donne déjà les bonnes permissions pour publier.
Remplacez le contenu du fichier “.gitlab-ci.yml” par ceci :
build-docker-image-to-dockerhub:
image:
name: moby/buildkit:rootless
entrypoint: [""]
stage: build
variables:
DOCKER_HUB_PROJECT: "devops"
BUILDKITD_FLAGS: --oci-worker-no-process-sandbox
DOCKER_CONFIG: "$CI_PROJECT_DIR/.docker"
IMAGE_NAME: ${DOCKER_HUB_USER}/${DOCKER_HUB_PROJECT}
CACHE_IMAGE: ${IMAGE_NAME}:cache
IMAGE_TAG_SHA: ${IMAGE_NAME}:$CI_COMMIT_SHA
IMAGE_TAG_LATEST: ${IMAGE_NAME}:latest
before_script:
- mkdir -p "$DOCKER_CONFIG"
# BuildKit expects Docker Hub auth under the index.docker.io/v1 key.
- echo "{\"auths\":{\"https://index.docker.io/v1/\":{\"username\":\"$DOCKER_HUB_USER\",\"password\":\"$DOCKER_HUB_PASSWORD\"}}}" > "$DOCKER_CONFIG/config.json"
script:
- |
TAG_NAME=${CI_COMMIT_TAG:-$CI_COMMIT_REF_NAME}
buildctl-daemonless.sh build \
--frontend dockerfile.v0 \
--local context=. \
--local dockerfile=. \
--export-cache type=registry,ref=$CACHE_IMAGE \
--import-cache type=registry,ref=$CACHE_IMAGE \
--opt platform=linux/amd64,linux/arm64 \
--output type=image,\"name=$IMAGE_TAG_SHA,$IMAGE_TAG_LATEST,${IMAGE_NAME}:$TAG_NAME\",push=true
Remplacez la variable DOCKER_HUB_PROJECT par le nom de votre repository sur Docker Hub et mettez à
jour le dépôt sur GitLab.
Dès que le runner aura fait son travail, vous devriez avoir l’image multi-architectures dans votre compte Docker Hub avec les tags et les architectures :

L’image sur mon compte Docker Hub est publique et vous pouvez l’essayer sans autre avec la commande suivante :
docker run --rm supcik/devops:latest