
Vos builds Docker prennent trop de temps en CI/CD ? Vous devez supporter ARM et x86 avec la même image ? BuildKit est le moteur de construction moderne de Docker, intégré par défaut depuis la version 23.0. Ce guide vous montre comment exploiter ses fonctionnalités avancées : builds parallélisés, images multi-plateformes, cache distribué et secrets sécurisés.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Architecture BuildKit : comprendre LLB, frontends et drivers
- Gestion des builders : créer, inspecter et basculer entre instances
- Multi-plateforme : construire des images linux/amd64, linux/arm64 en une commande
- Cache avancé : registry, GHA, S3 pour accélérer les builds CI/CD
- Secrets au build : monter des credentials sans les exposer dans l’image
Analogie : l’usine de construction modulaire
Section intitulée « Analogie : l’usine de construction modulaire »Pensez à BuildKit comme une usine de construction modulaire :
| Concept BuildKit | Équivalent usine |
|---|---|
| Frontend (dockerfile:1) | Plan de l’architecte → traduit en instructions usine |
| LLB (Low-Level Build) | Ordres de fabrication standardisés |
| DAG Solver | Chef d’atelier qui parallélise les tâches indépendantes |
| Drivers | Différents sites de production (local, conteneur, Kubernetes) |
| Cache | Entrepôt de pièces pré-fabriquées pour réutilisation |
Prérequis
Section intitulée « Prérequis »- Docker 23.0+ (BuildKit activé par défaut) ou Docker Desktop
- Connaissances de base en Dockerfile
- Pour multi-plateforme : QEMU ou accès à des runners ARM natifs
Vérifier votre version :
docker version --format '{{.Server.Version}}'# 24.0.0 ou supérieur
docker buildx version# github.com/docker/buildx v0.12.0 ou supérieurArchitecture de BuildKit
Section intitulée « Architecture de BuildKit »Qu’est-ce que BuildKit ?
Section intitulée « Qu’est-ce que BuildKit ? »BuildKit est le moteur de construction d’images de conteneurs développé par le projet Moby. Il remplace l’ancien builder Docker et apporte des améliorations majeures :
| Fonctionnalité | Ancien builder | BuildKit |
|---|---|---|
| Parallélisation | Séquentiel | ✅ Étapes indépendantes en parallèle |
| Cache | Par couche | ✅ Par checksum de contenu |
| Multi-plateforme | ❌ Non | ✅ Natif avec --platform |
| Secrets au build | ❌ Impossible | ✅ --mount=type=secret |
| SSH forwarding | ❌ Impossible | ✅ --mount=type=ssh |
| Cache distribué | ❌ Non | ✅ Registry, GHA, S3 |
Les composants clés
Section intitulée « Les composants clés »-
Frontend : convertit votre Dockerfile en instructions LLB
Le frontend par défaut est
docker/dockerfile:1. Vous pouvez en utiliser d’autres (comme Buildpacks) en spécifiant# syntax=en première ligne. -
LLB (Low-Level Build) : format binaire intermédiaire
C’est le “langage machine” de BuildKit. Chaque opération est un nœud dans un graphe de dépendances (DAG).
-
DAG Solver : optimise l’exécution
- Détecte les étapes indépendantes pour les paralléliser
- Skip les étapes dont le résultat est déjà en cache
- Optimise le transfert des fichiers depuis le contexte
-
Exporters : génèrent la sortie finale
image: image OCI vers Docker ou registrylocal: fichiers vers un dossier localtar: archive taroci: bundle OCI
Buildx : le plugin CLI
Section intitulée « Buildx : le plugin CLI »Buildx est le plugin Docker CLI qui expose toutes les fonctionnalités de BuildKit. Il remplace progressivement docker build par docker buildx build.
Les 4 drivers Buildx
Section intitulée « Les 4 drivers Buildx »| Driver | Description | Multi-arch | Cache avancé | Cas d’usage |
|---|---|---|---|---|
| docker | Utilise le daemon Docker local | ❌ | ❌ | Développement simple |
| docker-container | BuildKit dans un conteneur dédié | ✅ QEMU | ✅ | Recommandé pour CI/CD |
| kubernetes | Pods BuildKit sur un cluster K8s | ✅ | ✅ | Builds à grande échelle |
| remote | Se connecte à un buildkitd distant | ✅ | ✅ | Build distribué |
Gestion des builders
Section intitulée « Gestion des builders »Lister les builders disponibles
Section intitulée « Lister les builders disponibles »docker buildx lsSortie typique :
NAME/NODE DRIVER/ENDPOINT STATUS BUILDKIT PLATFORMSdefault * docker default default running v0.27.0 linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/386L’astérisque * indique le builder actif. Le driver docker par défaut utilise le daemon Docker local et a des limitations (pas de multi-plateforme, pas de cache distribué).
Créer un builder docker-container
Section intitulée « Créer un builder docker-container »Pour débloquer multi-plateforme et cache avancé, créez un builder avec le driver docker-container :
docker buildx create \ --name mybuilder \ --driver docker-container \ --bootstrap \ --use| Option | Description |
|---|---|
--name | Nom du builder |
--driver | Type de driver (docker-container recommandé) |
--bootstrap | Démarre immédiatement le conteneur BuildKit |
--use | Définit ce builder comme défaut |
Vérification :
docker buildx inspect mybuilderName: mybuilderDriver: docker-containerLast Activity: 2026-01-21 16:57:35 +0000 UTC
Nodes:Name: mybuilder0Endpoint: unix:///var/run/docker.sockStatus: runningBuildKit version: v0.27.0Platforms: linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/386Labels: org.mobyproject.buildkit.worker.executor: oci org.mobyproject.buildkit.worker.snapshotter: overlayfsLe builder est maintenant actif et prêt à exécuter des builds multi-plateformes. Notez que sans QEMU installé, seules les architectures compatibles avec votre machine hôte sont disponibles.
Basculer entre builders
Section intitulée « Basculer entre builders »Une fois plusieurs builders créés, vous pouvez basculer entre eux :
# Utiliser un builder spécifiquedocker buildx use mybuilder
# Vérifier le builder actifdocker buildx lsNAME/NODE DRIVER/ENDPOINT STATUS BUILDKIT PLATFORMSmybuilder* docker-container mybuilder0 unix:///var/run/docker.sock running v0.26.3 linux/amd64 (+3), linux/386default docker default default running v0.26.2 linux/amd64 (+3)# Revenir au builder par défautdocker buildx use defaultSupprimer un builder
Section intitulée « Supprimer un builder »Quand un builder n’est plus nécessaire, vous pouvez le supprimer :
# Supprimer en conservant le cache (volume Docker)docker buildx rm --keep-state mybuilder
# Supprimer complètement (builder + cache)docker buildx rm mybuilderExemple concret :
# Builder corrompu ou plantagedocker buildx rm --keep-state ci-builder
# Recréer avec le même nomdocker buildx create --name ci-builder --driver docker-container --use
# Le cache est toujours là !Builds multi-plateformes
Section intitulée « Builds multi-plateformes »L’un des avantages majeurs de BuildKit est la capacité de construire des images pour plusieurs architectures en une seule commande.
Prérequis QEMU (Linux sans Docker Desktop)
Section intitulée « Prérequis QEMU (Linux sans Docker Desktop) »Sur Docker Engine Linux, installez QEMU pour l’émulation :
docker run --privileged --rm tonistiigi/binfmt --install allVérification :
docker buildx inspect --bootstrap# Doit lister linux/arm64, linux/arm/v7, etc.Construire pour plusieurs plateformes
Section intitulée « Construire pour plusieurs plateformes »docker buildx build \ --platform linux/amd64,linux/arm64 \ --tag mon-registry/mon-app:1.0 \ --push \ .| Option | Description |
|---|---|
--platform | Liste des architectures cibles |
--push | Pousse directement vers la registry (obligatoire pour multi-arch) |
--load | Charge dans Docker local (impossible en multi-arch) |
Les 3 stratégies multi-plateforme
Section intitulée « Les 3 stratégies multi-plateforme »Le plus simple : BuildKit émule les architectures non-natives via QEMU.
docker buildx build --platform linux/amd64,linux/arm64 -t myapp --push .Avantages :
- Aucune configuration complexe
- Fonctionne partout
Inconvénients :
- Lent pour les compilations (10-50× plus lent)
- Consomme beaucoup de CPU
Le plus rapide : utilisez des runners natifs pour chaque architecture.
# Créer un builder multi-nodesdocker buildx create --name multi --driver docker-container --use node-amd64docker buildx create --append --name multi node-arm64
docker buildx build --platform linux/amd64,linux/arm64 -t myapp --push .Avantages :
- Performance native
- Pas d’émulation
Inconvénients :
- Infrastructure plus complexe
- Nécessite des runners ARM
Le plus efficace pour les langages compilés (Go, Rust) : compilez depuis l’architecture native vers la cible.
# syntax=docker/dockerfile:1FROM --platform=$BUILDPLATFORM golang:1.21-alpine AS builderARG TARGETOS TARGETARCHWORKDIR /appCOPY . .RUN GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -o /app/main .
FROM alpine:3.19COPY --from=builder /app/main /mainENTRYPOINT ["/main"]docker buildx build --platform linux/amd64,linux/arm64 -t myapp --push .Avantages :
- Vitesse native
- Pas d’émulation
Inconvénients :
- Requiert un support du langage (Go, Rust)
- Ne fonctionne pas pour tous les projets
Cache avancé
Section intitulée « Cache avancé »BuildKit supporte plusieurs backends de cache pour partager le cache entre builds, particulièrement utile en CI/CD où chaque job démarre sur un runner frais.
Les backends de cache
Section intitulée « Les backends de cache »| Backend | Description | Driver requis | Cas d’usage |
|---|---|---|---|
| inline | Cache embarqué dans l’image | Tous | Simple, image unique |
| registry | Cache séparé dans une registry | docker-container | CI/CD avec registry privée |
| local | Fichiers sur le système de fichiers | docker-container | Builds locaux |
| gha | GitHub Actions cache | docker-container | GitHub Actions |
| s3 | AWS S3 bucket | docker-container | CI/CD multi-cloud |
| azblob | Azure Blob Storage | docker-container | CI/CD Azure |
Cache registry (recommandé pour CI/CD)
Section intitulée « Cache registry (recommandé pour CI/CD) »Le cache est stocké dans une image séparée sur votre registry :
docker buildx build \ --cache-from type=registry,ref=mon-registry/myapp:cache \ --cache-to type=registry,ref=mon-registry/myapp:cache,mode=max \ --tag mon-registry/myapp:1.0 \ --push \ .| Paramètre | Description |
|---|---|
mode=min | Cache uniquement les couches de l’image finale (défaut) |
mode=max | Cache toutes les couches, y compris les stages intermédiaires |
Cache GitHub Actions
Section intitulée « Cache GitHub Actions »Idéal pour les workflows GitHub Actions :
name: Build and Push
on: push: branches: [main]
jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4
- name: Set up Docker Buildx uses: docker/setup-buildx-action@v3
- name: Login to Registry uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push uses: docker/build-push-action@v6 with: context: . push: true tags: ghcr.io/${{ github.repository }}:${{ github.sha }} cache-from: type=gha cache-to: type=gha,mode=maxImporter depuis plusieurs caches
Section intitulée « Importer depuis plusieurs caches »Vous pouvez importer le cache depuis plusieurs sources (branche courante + main) :
docker buildx build \ --cache-from type=registry,ref=registry/app:cache-$BRANCH \ --cache-from type=registry,ref=registry/app:cache-main \ --cache-to type=registry,ref=registry/app:cache-$BRANCH,mode=max \ --push .Secrets au build
Section intitulée « Secrets au build »BuildKit permet de monter des secrets pendant le build sans qu’ils n’apparaissent dans l’image finale.
Pourquoi c’est important ?
Section intitulée « Pourquoi c’est important ? »# ❌ DANGER : le secret reste dans l'historique des couchesARG NPM_TOKENRUN echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > .npmrc \ && npm ci \ && rm .npmrc# Le secret est visible avec "docker history"Utiliser —mount=type=secret
Section intitulée « Utiliser —mount=type=secret »# syntax=docker/dockerfile:1FROM node:20-alpineWORKDIR /appCOPY package*.json ./
# ✅ Secret monté temporairement, jamais dans l'imageRUN --mount=type=secret,id=npmrc,target=/root/.npmrc \ npm ci --omit=dev
COPY . .CMD ["node", "index.js"]Commande de build :
docker buildx build \ --secret id=npmrc,src=$HOME/.npmrc \ -t myapp .SSH forwarding
Section intitulée « SSH forwarding »Pour cloner des repos privés sans exposer la clé SSH :
# syntax=docker/dockerfile:1FROM alpineRUN apk add --no-cache git openssh-client
# Clone avec la clé SSH de l'hôteRUN --mount=type=ssh \ git clone git@github.com:org/private-repo.git /appdocker buildx build --ssh default -t myapp .Dépannage
Section intitulée « Dépannage »Le cache n’est jamais utilisé
Section intitulée « Le cache n’est jamais utilisé »Symptôme : chaque build recommence de zéro.
| Cause | Solution |
|---|---|
Driver docker | Passez à docker-container |
--no-cache dans la commande | Retirer cette option |
--cache-from incorrect | Vérifier le ref de la registry |
| Registry inaccessible | Vérifier les credentials |
# Vérifier le driver actifdocker buildx inspect
# Voir les logs du builderdocker logs buildx_buildkit_mybuilder0Build multi-plateforme échoue
Section intitulée « Build multi-plateforme échoue »Symptôme : erreur exec format error ou build qui plante.
| Cause | Solution |
|---|---|
| QEMU non installé | docker run --privileged --rm tonistiigi/binfmt --install all |
| Image de base non disponible | Vérifier que l’image existe pour la plateforme cible |
| Commandes incompatibles | Utiliser des images multi-arch ou cross-compiler |
Espace disque saturé
Section intitulée « Espace disque saturé »BuildKit accumule du cache dans son volume. Sur des builds CI/CD répétés, cela peut rapidement atteindre plusieurs Go. Nettoyez régulièrement :
# Voir l'espace utilisé par builderdocker buildx duExemple de sortie :
ID RECLAIMABLE SIZE LAST ACCESSED6qz04izv37q7h9bz6swhoguxm true 0B 2 minutes agosnf1d9cpv9w1w4p9shvb10niv* true 8.192kB 2 minutes agoswr54o7l18c7mp9ik8ckv64wo* true 8.192kB 2 minutes agopqodoch6223u35j2giitjl4vz* true 20.48kB 2 minutes agoi47mgx85k11bu1c6trxwykg3e true 40.97MB 2 minutes agoReclaimable: 41.01MBTotal: 41.01MBLes entrées marquées RECLAIMABLE: true peuvent être supprimées sans impact sur les futurs builds (mais ils seront plus lents sans cache).
# Nettoyer le cache inutilisé (garde les couches récentes)docker buildx prune
# Nettoyer tout (libère le maximum d'espace)docker buildx prune --all
# Nettoyer un builder spécifiquedocker buildx prune --builder mybuilderBonnes pratiques
Section intitulée « Bonnes pratiques »Performance
Section intitulée « Performance »- Utilisez
mode=maxpour le cache en CI/CD avec des builds multi-stage - Cross-compilez quand le langage le supporte (Go, Rust)
- Parallélisez les étapes indépendantes dans le Dockerfile
- Utilisez les cache mounts pour npm, pip, apt
Sécurité
Section intitulée « Sécurité »- Jamais de secrets en ARG/ENV — utilisez
--mount=type=secret - Vérifiez les images de base avec un scanner (Trivy, Grype)
- Utilisez des tags immutables ou des digests pour la reproductibilité
- Activez la signature d’images avec Docker Content Trust
Organisation
Section intitulée « Organisation »- Variables d’environnement pour TAG, REGISTRY dans vos scripts CI
- Targets séparés pour dev/staging/prod si vous utilisez Docker Bake
- Documentation des commandes de build dans le README du projet
Testez vos connaissances
Section intitulée « Testez vos connaissances »Vérifiez votre compréhension de BuildKit et Buildx :
Contrôle de connaissances
Validez vos connaissances avec ce quiz interactif
Informations
- Le chronomètre démarre au clic sur Démarrer
- Questions à choix multiples, vrai/faux et réponses courtes
- Vous pouvez naviguer entre les questions
- Les résultats détaillés sont affichés à la fin
Lance le quiz et démarre le chronomètre
Vérification
(0/0)Profil de compétences
Quoi faire maintenant
Ressources pour progresser
Des indices pour retenter votre chance ?
Nouveau quiz complet avec des questions aléatoires
Retravailler uniquement les questions ratées
Retour à la liste des certifications
À retenir
Section intitulée « À retenir »- BuildKit est le moteur de build par défaut depuis Docker 23.0, avec parallélisation et cache intelligent
- Buildx est le plugin CLI qui expose toutes les fonctionnalités avancées de BuildKit
- Driver
docker-containerest requis pour multi-plateforme et cache distribué - 3 stratégies multi-arch : QEMU (simple), nodes natifs (rapide), cross-compilation (optimal)
- Cache distribué (
registry,gha,s3) : essentiel pour accélérer les builds CI/CD - Secrets au build :
--mount=type=secretpour ne jamais exposer de credentials dans l’image
Questions fréquentes
Section intitulée « Questions fréquentes »Images de release signées
C'est la première version où les images officielles sont signées cryptographiquement via Docker GitHub Builder. Vous pouvez vérifier leur provenance :cosign verify moby/buildkit:v0.27.0 \
--certificate-identity-regexp=".*" \
--certificate-oidc-issuer-regexp=".*"
Cache GitHub signé
Le backend de cachegha (GitHub Actions) supporte maintenant un cache signé cryptographiquement, vérifié automatiquement à l'import :docker buildx build \
--cache-from type=gha,signed=true \
--cache-to type=gha,signed=true \
-t myapp .
Autres améliorations
- Dockerfile frontend v1.21.0 intégré
- Push parallèle des blobs de cache registry (plus rapide)
- Meilleure gestion des clés expirées dans la vérification des signatures Git
- Fix concurrence dans l'évaluation des policies source (évite des panics)
Pourquoi c'est important ?
Les images de builder sont une surface d'attaque critique. Une image BuildKit compromise peut injecter du code malveillant dans tous vos artefacts. La signature permet de vérifier que l'image provient bien du projet Moby.docker buildx build. En résumé : BuildKit fait le travail, Buildx vous permet de le piloter.- BuildKit : parallélisation, cache intelligent, secrets
- Buildx : gestion des builders, multi-plateforme, bake
# Option 1 : variable d'environnement
export DOCKER_BUILDKIT=1
docker build .
# Option 2 : configuration daemon (/etc/docker/daemon.json)
{
"features": {
"buildkit": true
}
}
Pour vérifier : docker buildx version doit afficher la version du plugin.docker-container pour la CI/CD. C'est le seul qui supporte :- ✅ Builds multi-plateformes (via QEMU)
- ✅ Cache distribué (registry, GHA, S3)
- ✅ Exports avancés (OCI, tar)
docker buildx create --name ci-builder --driver docker-container --use
Le driver docker (par défaut) est limité au développement local.docker-container :# 1. Créer un builder multi-arch (une seule fois)
docker buildx create --name multiarch --driver docker-container --use
# 2. Installer QEMU pour l'émulation (Linux sans Docker Desktop)
docker run --privileged --rm tonistiigi/binfmt --install all
# 3. Construire et pousser
docker buildx build \
--platform linux/amd64,linux/arm64 \
--tag registry/app:1.0 \
--push .
Important : utilisez --push car --load ne fonctionne pas en multi-plateforme.--cache-from et --cache-to :docker buildx build \
--cache-from type=registry,ref=registry/app:cache \
--cache-to type=registry,ref=registry/app:cache,mode=max \
--tag registry/app:1.0 \
--push .
Backends disponibles :registry: image de cache sur votre registrygha: cache natif GitHub Actionss3: bucket AWS S3azblob: Azure Blob Storage
mode=max pour cacher les stages intermédiaires.--mount=type=secret dans le Dockerfile :# syntax=docker/dockerfile:1
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
# Le secret est monté temporairement, jamais dans l'image
RUN --mount=type=secret,id=npmrc,target=/root/.npmrc \
npm ci --omit=dev
docker buildx build --secret id=npmrc,src=$HOME/.npmrc -t app .
Avantages :- Le secret n'apparaît pas dans
docker history - Il n'est pas inclus dans les couches de l'image
# docker-bake.hcl
target "app" {
dockerfile = "Dockerfile"
tags = ["registry/app:latest"]
platforms = ["linux/amd64", "linux/arm64"]
cache-from = ["type=registry,ref=registry/app:cache"]
}
docker buildx bake --push
Utilisez Bake quand :- Vous avez plusieurs images à construire
- Les commandes
docker builddeviennent trop longues - Vous voulez versionner la configuration dans le repo
# Installer les émulateurs QEMU
docker run --privileged --rm tonistiigi/binfmt --install all
# Vérifier les plateformes supportées
docker buildx inspect --bootstrap
Autres causes possibles :- L'image de base n'existe pas pour la plateforme cible
- Une commande dans le Dockerfile est incompatible avec l'architecture
# Voir l'espace utilisé
docker buildx du
# Supprimer le cache inutilisé (garde les couches récentes)
docker buildx prune
# Tout supprimer (libère le maximum d'espace)
docker buildx prune --all
# Supprimer le cache d'un builder spécifique
docker buildx prune --builder mybuilder
Conseil CI/CD : ajoutez docker buildx prune --all -f en fin de pipeline si l'espace disque est limité.| Mode | Ce qui est caché | Cas d'usage |
|---|---|---|
mode=min |
Uniquement les couches de l'image finale | Images simples, sans multi-stage |
mode=max |
Toutes les couches, y compris les stages intermédiaires | Builds multi-stage |
FROM golang AS builder # ← Caché seulement avec mode=max
RUN go build -o /app
FROM alpine # ← Caché avec min et max
COPY --from=builder /app /app
Recommandation : utilisez mode=max en CI/CD pour ne pas reconstruire le stage builder à chaque fois.