Docker Buildx multi-architecture : configurer un CI Mac distant en 2026
Ce guide accompagne les équipes DevOps depuis le choix de la topologie jusqu’à l’acceptation d’un pipeline Docker Buildx multi-architecture. Vous y trouverez une répartition claire entre nœuds ARM64 et AMD64, une procédure de connexion d’un Mac distant, la gestion du cache, la publication du Manifest et les tests de reprise après redémarrage.
Sommaire
- Avant le déploiement : attribuer une responsabilité à chaque nœud
- Première étape : vérifier le Mac avant de créer le Builder
- Deuxième étape : créer un contexte distant et un Builder multi-nœuds
- Troisième étape : valider séparément ARM64 et AMD64
- Quatrième étape : brancher le CI, le cache et la publication
- FAQ de mise en œuvre
- Cinquième étape : tester la permanence et la reprise
- Grille d’acceptation avant l’entrée en production
- Décision finale : Mac seul, nœuds mixtes ou retour en arrière
Le symptôme est connu : un seul Mac Apple Silicon construit toutes les plateformes avec QEMU, puis la compilation AMD64 devient lente ou produit une image jamais validée nativement.
La solution la plus sûre consiste à faire du Mac distant le Builder ARM64 permanent, à confier AMD64 à un nœud natif ou à une vraie chaîne de compilation croisée, puis à laisser Docker Buildx assembler et publier le Manifest multi-architecture.
Cette méthode évite de confondre quatre réalités différentes : l’architecture de l’hôte, la plateforme annoncée par le nœud Buildx, la plateforme cible de l’image et l’architecture réellement utilisée pendant une compilation dans le conteneur.
Cet article s’adresse aux ingénieurs DevOps, responsables de plateformes et développeurs backend qui publient simultanément des images linux/arm64 et linux/amd64. Il convient aussi aux équipes qui envisagent un Mac Apple Silicon distant comme nœud CI permanent et veulent l’accepter avec des preuves plutôt qu’avec un simple test de connexion.
Avant le déploiement : attribuer une responsabilité à chaque nœud
Docker documente trois familles de stratégies pour les images multi-plateformes : émulation avec QEMU, compilation croisée et construction sur plusieurs nœuds natifs. Ces stratégies ne produisent pas les mêmes garanties ; elles sont décrites dans la documentation officielle des builds multi-plateformes.
Un Mac Apple Silicon peut donc construire une image linux/amd64, mais cela signifie généralement que les instructions AMD64 sont exécutées par émulation. Ce n’est pas une exécution AMD64 native. Le résultat peut être acceptable pour une image dont les étapes sont simples, mais il devient moins prévisible dès que le Dockerfile compile du code, lance un outil dépendant de l’architecture ou compresse de nombreux artefacts.
La topologie de départ à privilégier est la suivante :
- le Mac Apple Silicon distant construit et exécute les validations
linux/arm64; - un nœud AMD64 natif construit
linux/amd64, si le projet contient des étapes sensibles à l’architecture ; - une chaîne de compilation croisée remplace le nœud AMD64 uniquement lorsque le langage, les dépendances et les tests le permettent ;
- Docker Buildx et BuildKit réunissent les sorties et publient une référence multi-architecture.
Ne décidez pas d’ajouter un Mac uniquement parce que le pipeline contient le mot « ARM64 ». Examinez trois éléments dans vos journaux actuels : la plateforme effectivement sélectionnée, l’étape qui échoue ou ralentit, et les lignes indiquant une réutilisation du cache. Une compilation qui échoue à cause d’un binaire précompilé ne se corrige pas simplement en ajoutant davantage de puissance ; elle nécessite une dépendance compatible ou une autre stratégie de build.
Pour votre estimation initiale, attribuez à chaque option un score de décision, et non une note de performance universelle :
| Option | ARM64 natif | AMD64 natif | Complexité | Usage recommandé |
|---|---|---|---|---|
| Mac seul avec émulation | Oui | Non | Faible au départ | Prototype, dépannage et images simples |
| Mac + compilation croisée | Oui | Selon le projet | Moyenne | Langages et toolchains maîtrisés |
| Mac + nœud AMD64 | Oui | Oui | Plus élevée | Publication régulière et compilation sensible |
Le score est favorable à la troisième option lorsque la fiabilité des artefacts compte davantage que la simplicité initiale. Il devient favorable à la deuxième si votre chaîne de compilation croisée est déjà testée et si les tests d’exécution ne dépendent pas d’un environnement AMD64 complet.
Première étape : vérifier le Mac avant de créer le Builder
Commencez par confirmer que le poste distant est réellement un Mac Apple Silicon et non seulement un client de connexion utilisé depuis une machine ARM. Cette distinction concerne l’hôte qui exécute Docker, pas l’ordinateur depuis lequel vous lancez SSH.
Vérifiez ensuite les éléments suivants :
- l’accès à macOS est opérationnel avec un compte réservé au CI ;
- Docker Desktop est installé et démarré dans le compte qui exécutera les builds ;
- la commande
docker buildx versionrépond ; docker infoconfirme que le démon Docker est accessible ;- le stockage prévu peut accueillir les couches temporaires, les images locales et les journaux ;
- la plateforme remontée par le nœud correspond à
linux/arm64.
La procédure officielle d’installation de Docker Desktop sur macOS doit être vérifiée au moment du déploiement, car les prérequis et les versions supportées peuvent évoluer. De même, la présence de l’exécutable Buildx ne prouve pas que le Builder choisi est initialisé ni que son nœud est disponible.
Utilisez des noms neutres dans vos commandes afin de pouvoir les transposer sans exposer votre infrastructure :
export MAC_CONTEXT=<CONTEXT_MAC>
export BUILDER_NAME=<BUILDER_MULTIARCH>
export IMAGE_ARM64=<REGISTRY>/<IMAGE>:<TAG>-arm64
export IMAGE_AMD64=<REGISTRY>/<IMAGE>:<TAG>-amd64
Ne remplacez pas ces variables par un nom d’hôte, un compte ou une adresse de registre réelle dans un document partagé. Le jeton de registre doit être limité au dépôt nécessaire et ne doit pas être placé dans le Dockerfile.
Deuxième étape : créer un contexte distant et un Builder multi-nœuds
Le compte CI du Mac doit être distinct de votre compte d’administration. Pour un accès par SSH, appliquez les contrôles recommandés dans la documentation Docker sur la protection de l’accès au démon : clé dédiée, permissions minimales, rotation et canal de maintenance indépendant.
Créez ensuite un contexte Docker vers le démon distant :
docker context create <CONTEXT_MAC> \
--docker "host=ssh://<CI_USER>@<MAC_HOST>"
Le nom <MAC_HOST> reste volontairement un emplacement réservé. Dans un environnement réel, vous pouvez utiliser un nom DNS interne, mais vous devez conserver une méthode d’administration locale ou hors bande. Si la création échoue, ne modifiez pas directement le contexte de production : testez d’abord SSH, puis l’accès Docker, puis la création du Builder.
Initialisez le Builder sur le premier nœud :
docker buildx create \
--name <BUILDER_MULTIARCH> \
--driver docker-container \
--use \
<CONTEXT_MAC>
Ajoutez ensuite le nœud AMD64 ou le contexte de compilation croisée selon votre choix :
docker buildx create \
--name <BUILDER_MULTIARCH> \
--append \
<CONTEXT_AMD64>
Les options de création et d’ajout d’un nœud sont détaillées dans la référence officielle de docker buildx create. Contrôlez immédiatement l’état :
docker buildx inspect <BUILDER_MULTIARCH> --bootstrap
Vous devez lire la liste des plateformes annoncées par chaque nœud et vérifier qu’elles correspondent à la topologie décidée. Le pilote docker et le pilote docker-container n’offrent pas exactement les mêmes possibilités de cache et d’isolement ; la comparaison officielle des pilotes Builder doit guider votre choix plutôt qu’un copier-coller trouvé dans un ancien pipeline.
Les versions de Docker Desktop, Buildx et BuildKit doivent être relevées dans votre inventaire. Pour la version de Buildx, consultez la page officielle des versions du projet le jour de l’installation, puis testez la version retenue sur un nœud isolé avant toute mise à niveau du pool CI.
Troisième étape : valider séparément ARM64 et AMD64
Ne commencez pas par le Dockerfile de production. Utilisez un Dockerfile minimal qui permet de contrôler l’architecture visible depuis l’image :
FROM alpine:3.20
ARG TARGETPLATFORM
ARG TARGETARCH
RUN printf 'target=%s arch=%s\n' "$TARGETPLATFORM" "$TARGETARCH"
CMD ["sh", "-c", "uname -a"]
La version d’image employée ici n’est pas une recommandation de production : remplacez-la par une référence approuvée dans votre registre interne. Le but est de distinguer la cible demandée par Buildx de l’architecture sur laquelle une commande s’exécute.
Construisez d’abord ARM64 sur le Mac :
docker buildx build \
--builder <BUILDER_MULTIARCH> \
--platform linux/arm64 \
--tag <IMAGE_ARM64> \
--push .
Puis testez AMD64 avec le nœud prévu :
docker buildx build \
--builder <BUILDER_MULTIARCH> \
--platform linux/amd64 \
--tag <IMAGE_AMD64> \
--push .
Si vous choisissez QEMU pour AMD64, notez explicitement dans le rapport quelle étape a été exécutée sous émulation. Ne transformez pas un build terminé en preuve de performance : l’émulation peut passer sur le Dockerfile minimal et échouer sur un compilateur, un installeur ou un binaire natif du projet réel.
Examinez également les deux images en les lançant sur des hôtes correspondant à leur plateforme, lorsque votre infrastructure de test le permet. Une image poussée avec succès n’est pas encore une image validée ; il faut vérifier son démarrage, ses bibliothèques dynamiques, ses scripts d’entrée et les éventuels appels à des outils natifs.
Quatrième étape : brancher le CI, le cache et la publication
Dans le pipeline, séparez les tâches par plateforme. Le job ARM64 doit sélectionner le contexte du Mac, tandis que le job AMD64 doit cibler le nœud AMD64 ou la chaîne de compilation croisée. Évitez que plusieurs tâches concurrentes partagent sans contrôle le même répertoire de travail, le même volume temporaire ou un Builder dont l’état peut être modifié par une autre exécution.
Pour le cache, utilisez une référence distincte de celle de l’image finale :
docker buildx build \
--platform linux/arm64 \
--cache-from type=registry,ref=<REGISTRY>/<CACHE>:arm64 \
--cache-to type=registry,ref=<REGISTRY>/<CACHE>:arm64,mode=max \
--tag <IMAGE_ARM64> \
--push .
Adaptez le backend au pilote et au registre réellement disponibles. Docker décrit les différences entre les backends de cache BuildKit ; le cache de compilation, l’image finale et le Manifest multi-architecture sont trois objets distincts. Réutiliser la même référence pour ces objets peut provoquer un remplacement inattendu ou rendre le diagnostic ambigu.
Une stratégie robuste est de produire d’abord deux références immuables, puis de créer le Manifest :
docker buildx imagetools create \
--tag <REGISTRY>/<IMAGE>:<TAG> \
<IMAGE_ARM64> \
<IMAGE_AMD64>
La commande officielle de création d’un Manifest multi-architecture montre le principe : chaque image doit exister avant l’assemblage. Après publication, inspectez le résultat :
docker buildx imagetools inspect <REGISTRY>/<IMAGE>:<TAG>
La documentation de buildx imagetools inspect est utile pour vérifier les plateformes, les digests et les métadonnées. Le contrôle doit échouer si l’une des plateformes attendues manque ; ne laissez pas le pipeline publier silencieusement un Manifest incomplet.
Les secrets de registre, les clés SSH et les jetons CI doivent être injectés par le gestionnaire de secrets de votre système d’intégration. Un clone propre, réalisé dans une session non interactive, doit pouvoir reproduire le build sans dépendre d’un contexte local oublié, d’une connexion personnelle ou d’un identifiant conservé dans le trousseau du poste d’administration.
FAQ de mise en œuvre
Les réponses ci-dessous précisent les décisions qui provoquent le plus souvent une mauvaise topologie.
Cinquième étape : tester la permanence et la reprise
Un Mac distant destiné au CI doit être évalué comme un nœud d’infrastructure, pas comme une session graphique ouverte. Fermez votre terminal SSH et vérifiez qu’un build lancé par le service CI continue selon le comportement attendu. Un processus dépendant d’un terminal interactif n’est pas une base fiable pour une file de production.
Simulez ensuite un redémarrage contrôlé du Mac. Après le retour du système, vérifiez séparément :
- la disponibilité de Docker Desktop ;
- l’accès du compte CI au démon Docker ;
- la validité du Docker Context ;
- l’état du Builder et de ses nœuds ;
- la lecture et l’écriture du cache ;
- la capacité à produire à nouveau une image ARM64 ;
- la présence des deux plateformes dans le Manifest final.
Testez aussi trois défaillances ciblées : le nœud AMD64 indisponible, le registre de cache inaccessible et l’échec d’une seule plateforme. Dans les deux derniers cas, le pipeline doit s’arrêter avant la publication d’un Manifest présenté comme complet. Une reprise manuelle documentée vaut mieux qu’un mécanisme automatique qui republie une référence partiellement construite.
La maintenance doit prévoir une fenêtre d’essai pour Docker Desktop, Buildx et BuildKit. Avant une mise à niveau, exécutez le Dockerfile représentatif sur un nœud isolé, comparez les journaux de sélection de plateforme et vérifiez que l’export du cache ainsi que l’inspection du Manifest se comportent comme avant.
Grille d’acceptation avant l’entrée en production
Utilisez cette liste après un clone propre du dépôt et non depuis votre poste d’administration :
- [ ] Le Mac distant est confirmé comme hôte Apple Silicon et annonce
linux/arm64. - [ ] Le compte CI possède uniquement les droits nécessaires pour construire et publier.
- [ ] Le Docker Context distant fonctionne sans session graphique personnelle.
- [ ] Le Builder affiche les nœuds et les plateformes attendus après
--bootstrap. - [ ] Le Dockerfile minimal produit une image ARM64 exécutable.
- [ ] Le Dockerfile réel termine ses étapes ARM64 sur le Mac sans dépendance interactive.
- [ ] Le chemin AMD64 est identifié comme natif, croisé ou émulé dans les journaux.
- [ ] Les références de cache sont séparées des références d’images finales.
- [ ] Les deux images sont inspectées avant la création du Manifest.
- [ ] Une plateforme manquante bloque la publication finale.
- [ ] Une déconnexion SSH ne tue pas un build déjà pris en charge par le CI.
- [ ] Un redémarrage du Mac est suivi d’une vérification du démon, du Builder et du cache.
- [ ] Le retour à l’ancienne version de Docker Desktop, Buildx ou BuildKit est documenté.
- [ ] Le pipeline possède un canal de maintenance distinct du contexte utilisé pour construire.
Décision finale : Mac seul, nœuds mixtes ou retour en arrière
Conservez un Mac Apple Silicon seul si vos images sont simples, si AMD64 reste occasionnel et si votre équipe accepte de traiter QEMU comme une solution de compatibilité, non comme une preuve d’exécution native. Cette configuration réduit le nombre de machines, mais concentre aussi les risques et peut rendre les échecs AMD64 difficiles à attribuer.
Choisissez une topologie mixte lorsque les images sont publiées régulièrement, que le Dockerfile compile des composants natifs ou que l’équipe doit vérifier ARM64 et AMD64 dans des environnements représentatifs. Le critère de décision n’est pas un seuil de durée générique : comparez les journaux de vos propres projets, les échecs reproductibles, la réutilisation du cache, le démarrage des images et la reprise après panne.
Revenez à la compilation croisée ou à une autre architecture de pipeline si le nœud AMD64 est rarement sollicité et si vos tests démontrent que les binaires produits sont identiques et exécutables sur la cible. À l’inverse, ajoutez un nœud AMD64 natif si les étapes critiques restent dépendantes de l’émulation ou si les erreurs ne peuvent pas être reproduites de manière stable.
Si votre environnement actuel repose sur un seul poste local, il impose souvent une disponibilité limitée, une architecture unique et une maintenance dépendante d’une session humaine. Une machine Linux standard ne remplace pas non plus un hôte Apple Silicon pour valider nativement ARM64. Dans ce cas précis, louer auprès de VPSMAC un Mac Apple Silicon distant pour un essai hebdomadaire ou mensuel permet de mesurer votre Dockerfile, votre cache, la publication et la reprise après redémarrage avant de l’intégrer au pool officiel. Vous pouvez examiner les nœuds Mac Apple Silicon disponibles, puis choisir une implantation adaptée à votre chaîne réseau, par exemple les nœuds M4 de Silicon Valley.
La bonne décision n’est donc pas de faire porter toutes les architectures à un seul Mac. C’est d’utiliser le Mac distant là où son exécution Apple Silicon apporte une validation réelle, de confier AMD64 au mécanisme le plus fiable pour votre projet, puis de refuser toute publication tant que les deux plateformes et la reprise opérationnelle n’ont pas été démontrées.