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
Impact réel
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 git@github.com: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 .
Attention
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.
Commentaires