L'essentiel
- BuildKit est le moteur de build par défaut depuis Docker 23.0, et ses cache mounts sont sa fonctionnalité la plus rentable :
RUN --mount=type=cache,target=/root/.cache/pip pip install -r requirements.txtréduit les rebuilds de 60 à 90 %, faisant tomber unpip installde 3 minutes à 10 secondes. - Ne passez jamais un secret par
ARGouENV: ces valeurs restent lisibles viadocker historyet dans les métadonnées de l'image. Utilisez les secret mounts BuildKit —RUN --mount=type=secret,id=pip_confcôté Dockerfile,docker buildx build --secret id=pip_conf,src=...côté commande — qui n'écrivent le secret dans aucune layer. - Le choix de l'image de base dicte la taille et la surface d'attaque : pour une application Go,
golang:1.22pèse 850 Mo,alpine15 Mo etscratch8 Mo. En production, Distroless (ni shell ni gestionnaire de paquets) pour les langages interprétés, scratch pour les binaires statiques, Alpine quand il faut pouvoir déboguer dans le conteneur. - Avec Compose v2, un
depends_onnu n'attend que la création du conteneur : utilisezcondition: service_healthypour attendre le healthcheck etcondition: service_completed_successfullypour les jobs de migration. Définissez toujoursdeploy.resources.limits— sans limite mémoire, un conteneur peut déclencher l'OOM killer du noyau et faire tomber les autres. - Le durcissement production :
read_only: trueavec untmpfspour les écritures,no-new-privileges:true,cap_drop: ALLpuis réajout minimal (NET_BIND_SERVICE), réseauinternal: truepour la base de données, rotation des logs (max-size/max-file), ettrivy image --severity HIGH,CRITICAL --exit-code 1en étape bloquante du pipeline. Jamais de tag:latesten production : SHA de commit ou semver.
Ce tutoriel suppose une connaissance de base de Docker (images, conteneurs, Dockerfile). Si vous débutez, consultez d'abord le guide d'installation et configuration de Docker.
Docker en développement vs Docker en production
La majorité des équipes utilisent Docker en développement sans difficulté. Un docker compose up, quelques volumes montés, et tout fonctionne. Mais le passage en production révèle des problématiques bien différentes : temps de build, taille des images, sécurité, gestion des ressources, monitoring et fiabilité.
En développement, on tolère des images de 2 Go, des builds de 10 minutes et des conteneurs qui tournent en root. En production, chaque mégaoctet compte, chaque seconde de build impacte le cycle de déploiement, et chaque conteneur root est une faille potentielle.
Ce guide couvre les techniques et outils indispensables pour exploiter Docker de manière professionnelle : BuildKit pour des builds rapides et sécurisés, les multi-stage builds pour des images minimales, Compose v2 pour l'orchestration, et les bonnes pratiques de sécurité, monitoring et réseau.
BuildKit : le moteur de build nouvelle génération
BuildKit est le moteur de build par défaut depuis Docker 23.0 (janvier 2023). Il remplace le builder legacy et apporte des améliorations majeures en termes de performance et de sécurité. Si vous utilisez une version récente de Docker, BuildKit est déjà actif.
Activation et configuration
Vérifiez que BuildKit est bien activé sur votre système :
# Vérifier la version et le builder actif
docker buildx version
docker buildx ls
# Forcer BuildKit pour les versions anciennes
export DOCKER_BUILDKIT=1
# Ou dans /etc/docker/daemon.json
{
"features": {
"buildkit": true
}
}
Créez un builder dédié avec des options avancées pour la production :
# Créer un builder avec un cache plus grand
docker buildx create --name production-builder \
--driver docker-container \
--config /etc/buildkitd.toml \
--use
# Configuration buildkitd.toml
[worker.oci]
max-parallelism = 4
gc = true
gckeepstorage = 10000 # 10 Go de cache
[[worker.oci.gcpolicy]]
keepBytes = 5000000000 # 5 Go minimum
keepDuration = 604800 # 7 jours
Cache mounts : accélérer les builds
Les cache mounts sont la fonctionnalité la plus impactante de BuildKit. Ils permettent de persister les caches de gestionnaires de paquets entre les builds, éliminant les téléchargements répétitifs.
# syntax=docker/dockerfile:1
FROM python:3.12-slim AS builder
WORKDIR /app
COPY requirements.txt .
# Cache mount pour pip : les paquets téléchargés sont réutilisés
RUN --mount=type=cache,target=/root/.cache/pip \
pip install --no-compile -r requirements.txt
# Équivalent pour Node.js
FROM node:20-alpine AS node-builder
WORKDIR /app
COPY package*.json ./
RUN --mount=type=cache,target=/root/.npm \
npm ci --production
# Équivalent pour apt
FROM debian:bookworm-slim
RUN --mount=type=cache,target=/var/cache/apt \
--mount=type=cache,target=/var/lib/apt/lists \
apt-get update && apt-get install -y --no-install-recommends \
curl ca-certificates
Les cache mounts réduisent typiquement les rebuilds de 60 à 90%. Un
pip install de 3 minutes passe à 10 secondes quand les paquets sont en cache.
Secrets mounts : injecter des credentials sans les exposer
Le problème classique : votre build a besoin d'un token pour accéder à un registre privé, un repo Git, ou une API. Avec l'ancien builder, le secret se retrouvait dans une layer de l'image. BuildKit résout ce problème avec les secret mounts.
# syntax=docker/dockerfile:1
FROM python:3.12-slim
# Le secret est monté en lecture seule, jamais stocké dans une layer
RUN --mount=type=secret,id=pip_conf,target=/etc/pip.conf \
pip install -r requirements.txt
# Accès à un repo privé via SSH
RUN --mount=type=ssh \
git clone [email protected]:private/repo.git
# Passer le secret au build
docker buildx build \
--secret id=pip_conf,src=$HOME/.pip/pip.conf \
--ssh default=$SSH_AUTH_SOCK \
-t monapp:latest .
N'utilisez jamais
ARG ou ENV pour passer des secrets. Ces valeurs sont visibles avec docker history et stockées dans les métadonnées de l'image.
Builds parallèles et cache distribué
BuildKit parallélise automatiquement les stages indépendants d'un Dockerfile. Combiné avec un cache distribué via un registry, les builds deviennent rapides même sur des runners CI éphémères.
# Build avec cache distribué via un registry
docker buildx build \
--cache-from type=registry,ref=registry.example.com/monapp:cache \
--cache-to type=registry,ref=registry.example.com/monapp:cache,mode=max \
-t monapp:latest \
--push .
# Cache local pour les builds fréquents
docker buildx build \
--cache-from type=local,src=/tmp/buildcache \
--cache-to type=local,dest=/tmp/buildcache,mode=max \
-t monapp:latest .
Le mode max exporte toutes les layers intermédiaires, pas uniquement celles de l'image finale. Cela maximise les hits de cache pour les stages de build.
Contenu Premium
Ce tutoriel avancé est réservé aux membres premium.
- Tous les tutoriels avancés
- Nouveaux contenus chaque semaine
- Suivi de progression
- Annulation à tout moment