infra / docker
Docker en production niveau expert
Explication
Ce que vous allez apprendre
- Configurer une politique de redémarrage adaptée (
unless-stopped,on-failure,always) - Comprendre pourquoi
live-restoreévite de couper tous les conteneurs lors d'une mise à jour du démon - Réaliser un rolling update sans interruption de service avec Swarm
- Exposer et exploiter des métriques Docker pour l'observabilité (cAdvisor, Prometheus)
- Appliquer une checklist de mise en production complète, sans en oublier une étape critique
Dans quel contexte ?
Un administrateur système doit mettre à jour le démon Docker sur un serveur de production qui héberge une dizaine de conteneurs critiques, un dimanche soir pour minimiser l'impact. Sans live-restore activé, redémarrer le démon coupe brutalement tous les conteneurs en même temps — un incident majeur, même en pleine nuit. Avec live-restore: true dans daemon.json, les conteneurs continuent de tourner normalement pendant toute la durée de la mise à jour du démon.
Cette leçon relie tout ce qui précède
Après avoir vu séparément les images, les volumes, les réseaux, les limites de ressources, les healthchecks et la sécurité, cette leçon assemble ces briques dans une vision d'ensemble : que faut-il vraiment surveiller et configurer pour qu'une application tourne de façon fiable en production, sans intervention humaine constante ?
| Restart policy | Comportement |
|---|---|
unless-stopped | Relance sauf arrêt manuel explicite |
on-failure:N | Relance jusqu'à N fois en cas d'échec seulement |
always | Relance systématiquement, y compris au boot du démon |
Bonne pratique
Avant toute mise en production, vérifie une checklist systématique plutôt que de te fier à la mémoire : tag précis, image scannée, utilisateur non-root, limites CPU/mémoire, healthcheck en place, logs bornés, live-restore activé, et un plan de rollback déjà testé.
La résilience automatique face aux pannes
Un conteneur peut planter pour de multiples raisons : bug applicatif, dépendance temporairement indisponible, ressource épuisée. Une politique de redémarrage (restart policy) indique à Docker quoi faire dans ce cas — le relancer automatiquement, éventuellement avec un nombre maximal de tentatives. C'est une première ligne de défense simple, avant même d'envisager un vrai orchestrateur.
Pourquoi live-restore change tout
Un point souvent ignoré des débutants : le démon Docker (dockerd) lui-même a parfois besoin d'être redémarré, par exemple pour une mise à jour. Sans l'option live-restore, redémarrer le démon coupe TOUS les conteneurs en cours d'exécution — un incident majeur en production. Avec cette option activée, les conteneurs continuent de fonctionner de façon autonome même pendant que le démon redémarre.
Déployer sans interruption de service
Remplacer une ancienne version par une nouvelle brutalement coupe le service le temps du basculement. Un "rolling update" remplace les instances progressivement, une par une (ou par petits groupes), en s'assurant que chaque nouvelle instance est réellement opérationnelle (grâce aux healthchecks) avant de retirer l'ancienne — le tout piloté par un orchestrateur comme Swarm, ou plus largement Kubernetes en production à grande échelle.
Une checklist n'est utile que si elle est vérifiée
Le vrai risque en production n'est pas de ne pas connaître ces bonnes pratiques individuellement, mais d'en oublier une seule au moment du déploiement. D'où l'intérêt de formaliser une checklist systématique (tag précis, scan de sécurité, utilisateur non-root, limites, healthcheck, logs bornés, plan de rollback) plutôt que de se fier à la mémoire.
Commandes & code
Docker en production niveau expert
# --- Restart policies : résilience automatique face aux crashs ---
docker run -d --restart unless-stopped mon-api:1.0 # relance sauf arrêt manuel explicite
docker run -d --restart on-failure:5 mon-api:1.0 # relance jusqu'à 5 fois en cas d'échec seulement
docker run -d --restart always mon-api:1.0 # relance systématiquement, y compris au boot du démon// /etc/docker/daemon.json : configuration globale du démon Docker en production
{
"log-driver": "json-file",
"log-opts": { "max-size": "10m", "max-file": "3" },
"default-ulimits": { "nofile": { "Name": "nofile", "Hard": 64000, "Soft": 64000 } },
"live-restore": true,
"storage-driver": "overlay2",
"metrics-addr": "127.0.0.1:9323",
"experimental": false
}sudo systemctl reload docker # applique daemon.json sans couper les conteneurs (live-restore)
# "live-restore": true est CRITIQUE en prod : les conteneurs continuent de tourner
# même si le démon Docker redémarre (mise à jour, crash du démon)
# --- Observabilité : métriques exposées par le démon (format Prometheus) ---
curl http://127.0.0.1:9323/metrics | head -30
# Exporter les métriques par conteneur vers Prometheus via cAdvisor
docker run -d --name cadvisor -p 8080:8080 \
-v /var/run:/var/run:ro -v /sys:/sys:ro -v /var/lib/docker/:/var/lib/docker:ro \
gcr.io/cadvisor/cadvisor# --- Rolling update sans coupure (hors orchestrateur, approche manuelle avec compose) ---
docker compose up -d --scale api=4 --no-recreate # démarre des instances supplémentaires
# puis retire progressivement les anciennes une fois les nouvelles healthy, derrière un load balancer
# --- Vers un orchestrateur pour de la vraie haute disponibilité ---
docker swarm init # initialise un cluster Swarm minimal
docker service create --name api --replicas 3 \
--update-parallelism 1 --update-delay 10s \
--restart-condition on-failure mon-api:1.0
docker service update --image mon-api:1.1 api # rolling update natif, une instance à la fois
docker service rollback api # rollback immédiat vers la version précédente
# En pratique, Kubernetes est le standard pour de l'orchestration à grande échelle# --- Sauvegarde et reprise après sinistre ---
# 1. Les images sont reproductibles depuis le registre : rien à sauvegarder côté image
# 2. Seules les DONNÉES (volumes) ont besoin d'un vrai backup, voir la leçon volumes
# 3. daemon.json, docker-compose.yml, .env.production : à versionner (hors secrets) dans un repo infra
# --- Checklist de mise en production ---
# - Tag précis (jamais "latest"), image scannée (trivy), utilisateur non-root
# - Limites CPU/mémoire définies, healthcheck en place, restart policy adaptée
# - Logs bornés (max-size/max-file), secrets externalisés (pas de ENV en dur)
# - live-restore activé, monitoring (cAdvisor/Prometheus) branché
# - Plan de rollback testé (docker service rollback, ou redeploy du tag précédent)
# --- Debug d'un incident en production sans redéployer ---
docker events --since 30m # historique des événements Docker récents
docker inspect --format '{{.State}}' mon-api # état complet au moment de l'incident
docker logs --since 30m mon-api > incident.log # capture pour analyse post-mortemRésumé
live-restore: truedansdaemon.jsonévite qu'une mise à jour du démon Docker coupe les conteneurs en production.- Un rolling update (Swarm
service update, ou équivalent Kubernetes) déploie sans interruption de service, avec rollback immédiat possible. - La checklist de prod tient en une phrase : tag précis + scan + non-root + limites + healthcheck + logs bornés + monitoring + plan de rollback.
Exercices pratiques
Mission : éviter une coupure totale lors d'une mise à jour du démon Docker
Objectif : Configurer live-restore avant une maintenance du démon et exécuter un rolling update sans interruption.
Contexte
Un administrateur doit mettre à jour le démon Docker sur un serveur hébergeant dix conteneurs critiques. Lors d'une précédente maintenance, sans live-restore, systemctl restart docker avait coupé tous les conteneurs en même temps.