Aller au contenu
Conteneurs & Orchestration medium

BuildKit et Buildx : construire des images Docker modernes

20 min de lecture

logo docker

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.

  • 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

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 SolverChef d’atelier qui parallélise les tâches indépendantes
DriversDifférents sites de production (local, conteneur, Kubernetes)
CacheEntrepôt de pièces pré-fabriquées pour réutilisation

Architecture BuildKit : Dockerfile → Frontend → LLB → DAG Solver → Image, avec drivers et backends de cache

  • 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 :

Fenêtre de terminal
docker version --format '{{.Server.Version}}'
# 24.0.0 ou supérieur
docker buildx version
# github.com/docker/buildx v0.12.0 ou supérieur

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 builderBuildKit
ParallélisationSéquentiel✅ Étapes indépendantes en parallèle
CachePar 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
  1. 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.

  2. 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).

  3. 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
  4. Exporters : génèrent la sortie finale

    • image : image OCI vers Docker ou registry
    • local : fichiers vers un dossier local
    • tar : archive tar
    • oci : bundle OCI

Buildx est le plugin Docker CLI qui expose toutes les fonctionnalités de BuildKit. Il remplace progressivement docker build par docker buildx build.

DriverDescriptionMulti-archCache avancéCas d’usage
dockerUtilise le daemon Docker localDéveloppement simple
docker-containerBuildKit dans un conteneur dédié✅ QEMURecommandé pour CI/CD
kubernetesPods BuildKit sur un cluster K8sBuilds à grande échelle
remoteSe connecte à un buildkitd distantBuild distribué
Fenêtre de terminal
docker buildx ls

Sortie typique :

NAME/NODE DRIVER/ENDPOINT STATUS BUILDKIT PLATFORMS
default * docker
default default running v0.27.0 linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/386

L’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é).

Pour débloquer multi-plateforme et cache avancé, créez un builder avec le driver docker-container :

Fenêtre de terminal
docker buildx create \
--name mybuilder \
--driver docker-container \
--bootstrap \
--use
OptionDescription
--nameNom du builder
--driverType de driver (docker-container recommandé)
--bootstrapDémarre immédiatement le conteneur BuildKit
--useDéfinit ce builder comme défaut

Vérification :

Fenêtre de terminal
docker buildx inspect mybuilder
Name: mybuilder
Driver: docker-container
Last Activity: 2026-01-21 16:57:35 +0000 UTC
Nodes:
Name: mybuilder0
Endpoint: unix:///var/run/docker.sock
Status: running
BuildKit version: v0.27.0
Platforms: linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/386
Labels:
org.mobyproject.buildkit.worker.executor: oci
org.mobyproject.buildkit.worker.snapshotter: overlayfs

Le 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.

Une fois plusieurs builders créés, vous pouvez basculer entre eux :

Fenêtre de terminal
# Utiliser un builder spécifique
docker buildx use mybuilder
# Vérifier le builder actif
docker buildx ls
NAME/NODE DRIVER/ENDPOINT STATUS BUILDKIT PLATFORMS
mybuilder* docker-container
mybuilder0 unix:///var/run/docker.sock running v0.26.3 linux/amd64 (+3), linux/386
default docker
default default running v0.26.2 linux/amd64 (+3)
Fenêtre de terminal
# Revenir au builder par défaut
docker buildx use default

Quand un builder n’est plus nécessaire, vous pouvez le supprimer :

Fenêtre de terminal
# Supprimer en conservant le cache (volume Docker)
docker buildx rm --keep-state mybuilder
# Supprimer complètement (builder + cache)
docker buildx rm mybuilder

Exemple concret :

Fenêtre de terminal
# Builder corrompu ou plantage
docker buildx rm --keep-state ci-builder
# Recréer avec le même nom
docker buildx create --name ci-builder --driver docker-container --use
# Le cache est toujours là !

L’un des avantages majeurs de BuildKit est la capacité de construire des images pour plusieurs architectures en une seule commande.

Build multi-plateforme : Dockerfile → Buildx → builds parallèles amd64/arm64 → Manifest List

Sur Docker Engine Linux, installez QEMU pour l’émulation :

Fenêtre de terminal
docker run --privileged --rm tonistiigi/binfmt --install all

Vérification :

Fenêtre de terminal
docker buildx inspect --bootstrap
# Doit lister linux/arm64, linux/arm/v7, etc.
Fenêtre de terminal
docker buildx build \
--platform linux/amd64,linux/arm64 \
--tag mon-registry/mon-app:1.0 \
--push \
.
OptionDescription
--platformListe des architectures cibles
--pushPousse directement vers la registry (obligatoire pour multi-arch)
--loadCharge dans Docker local (impossible en multi-arch)

Le plus simple : BuildKit émule les architectures non-natives via QEMU.

Fenêtre de terminal
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

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.

BackendDescriptionDriver requisCas d’usage
inlineCache embarqué dans l’imageTousSimple, image unique
registryCache séparé dans une registrydocker-containerCI/CD avec registry privée
localFichiers sur le système de fichiersdocker-containerBuilds locaux
ghaGitHub Actions cachedocker-containerGitHub Actions
s3AWS S3 bucketdocker-containerCI/CD multi-cloud
azblobAzure Blob Storagedocker-containerCI/CD Azure

Le cache est stocké dans une image séparée sur votre registry :

Fenêtre de terminal
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ètreDescription
mode=minCache uniquement les couches de l’image finale (défaut)
mode=maxCache toutes les couches, y compris les stages intermédiaires

Idéal pour les workflows GitHub Actions :

.github/workflows/build.yml
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=max

Vous pouvez importer le cache depuis plusieurs sources (branche courante + main) :

Fenêtre de terminal
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 .

BuildKit permet de monter des secrets pendant le build sans qu’ils n’apparaissent dans l’image finale.

# ❌ DANGER : le secret reste dans l'historique des couches
ARG NPM_TOKEN
RUN echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > .npmrc \
&& npm ci \
&& rm .npmrc
# Le secret est visible avec "docker history"
# syntax=docker/dockerfile:1
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
# ✅ Secret monté temporairement, jamais dans l'image
RUN --mount=type=secret,id=npmrc,target=/root/.npmrc \
npm ci --omit=dev
COPY . .
CMD ["node", "index.js"]

Commande de build :

Fenêtre de terminal
docker buildx build \
--secret id=npmrc,src=$HOME/.npmrc \
-t myapp .

Pour cloner des repos privés sans exposer la clé SSH :

# syntax=docker/dockerfile:1
FROM alpine
RUN apk add --no-cache git openssh-client
# Clone avec la clé SSH de l'hôte
RUN --mount=type=ssh \
git clone git@github.com:org/private-repo.git /app
Fenêtre de terminal
docker buildx build --ssh default -t myapp .

Symptôme : chaque build recommence de zéro.

CauseSolution
Driver dockerPassez à docker-container
--no-cache dans la commandeRetirer cette option
--cache-from incorrectVérifier le ref de la registry
Registry inaccessibleVérifier les credentials
Fenêtre de terminal
# Vérifier le driver actif
docker buildx inspect
# Voir les logs du builder
docker logs buildx_buildkit_mybuilder0

Symptôme : erreur exec format error ou build qui plante.

CauseSolution
QEMU non installédocker run --privileged --rm tonistiigi/binfmt --install all
Image de base non disponibleVérifier que l’image existe pour la plateforme cible
Commandes incompatiblesUtiliser des images multi-arch ou cross-compiler

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 :

Fenêtre de terminal
# Voir l'espace utilisé par builder
docker buildx du

Exemple de sortie :

ID RECLAIMABLE SIZE LAST ACCESSED
6qz04izv37q7h9bz6swhoguxm true 0B 2 minutes ago
snf1d9cpv9w1w4p9shvb10niv* true 8.192kB 2 minutes ago
swr54o7l18c7mp9ik8ckv64wo* true 8.192kB 2 minutes ago
pqodoch6223u35j2giitjl4vz* true 20.48kB 2 minutes ago
i47mgx85k11bu1c6trxwykg3e true 40.97MB 2 minutes ago
Reclaimable: 41.01MB
Total: 41.01MB

Les entrées marquées RECLAIMABLE: true peuvent être supprimées sans impact sur les futurs builds (mais ils seront plus lents sans cache).

Fenêtre de terminal
# 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écifique
docker buildx prune --builder mybuilder
  1. Utilisez mode=max pour le cache en CI/CD avec des builds multi-stage
  2. Cross-compilez quand le langage le supporte (Go, Rust)
  3. Parallélisez les étapes indépendantes dans le Dockerfile
  4. Utilisez les cache mounts pour npm, pip, apt
  1. Jamais de secrets en ARG/ENV — utilisez --mount=type=secret
  2. Vérifiez les images de base avec un scanner (Trivy, Grype)
  3. Utilisez des tags immutables ou des digests pour la reproductibilité
  4. Activez la signature d’images avec Docker Content Trust
  1. Variables d’environnement pour TAG, REGISTRY dans vos scripts CI
  2. Targets séparés pour dev/staging/prod si vous utilisez Docker Bake
  3. Documentation des commandes de build dans le README du projet

Vérifiez votre compréhension de BuildKit et Buildx :

Contrôle de connaissances

Validez vos connaissances avec ce quiz interactif

7 questions
5 min.
80% requis

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

  1. BuildKit est le moteur de build par défaut depuis Docker 23.0, avec parallélisation et cache intelligent
  2. Buildx est le plugin CLI qui expose toutes les fonctionnalités avancées de BuildKit
  3. Driver docker-container est requis pour multi-plateforme et cache distribué
  4. 3 stratégies multi-arch : QEMU (simple), nodes natifs (rapide), cross-compilation (optimal)
  5. Cache distribué (registry, gha, s3) : essentiel pour accélérer les builds CI/CD
  6. Secrets au build : --mount=type=secret pour ne jamais exposer de credentials dans l’image

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.