Ce guide est une checklist pratique et prête à copier-coller pour exécuter Docker en production. Elle couvre la configuration, la sécurité, les limites de ressources, le réseau, l'observabilité, les sauvegardes, les mises à niveau et la maintenance. Chaque section propose des exemples concrets à adapter selon votre contexte.
Introduction
Mettre Docker en production, c'est viser des builds reproductibles, des défauts sûrs, une observabilité solide et une gestion des changements sans stress. Le résultat attendu: une fiabilité plus élevée avec moins de rework et de surprises. Utilisez cette Docker checklist pour standardiser votre approche, appliquer des Docker best practices et accélérer vos livraisons.
Vue d'ensemble du workflow
Appliquez ces étapes à chaque service:
- Construire des images minimales et épinglées
- Configurer l'exécution en sécurité (utilisateur, capacités, FS)
- Isoler le réseau et n'exposer que le nécessaire
- Définir des limites de ressources et des healthchecks
- Brancher logs et métriques avec rétention bornée
- Persister l'état via des volumes nommés et tester les sauvegardes
- Mettre à niveau avec possibilité de rollback, valider via probes
- Maintenir hôtes et artefacts selon un calendrier
Astuce: des étapes petites et observables réduisent le rework et facilitent l'isolement des problèmes.
Socle de configuration
Checklist:
- Builds multi-étapes pour garder des images petites
- Épingler les images de base et outils par version (ou digest)
- Utilisateur non-root avec UID/GID fixes
- HEALTHCHECK dans l'image ou Compose
- .dockerignore strict pour des fichiers minimaux
- Labels de provenance (organisation, version, VCS, date de build)
Exemple Dockerfile (service Go):
# Étape build
FROM golang:1.22-alpine AS build
WORKDIR /src
RUN adduser -D -u 10001 app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags='-s -w' -o /out/app ./cmd/server
# Étape runtime
FROM alpine:3.20
RUN addgroup -g 10001 app \
&& adduser -D -u 10001 -G app app \
&& apk add --no-cache ca-certificates curl
WORKDIR /app
COPY --from=build /out/app /app/app
USER 10001:10001
EXPOSE 8080
HEALTHCHECK --interval=30s --timeout=3s --retries=3 \
CMD curl -fsS http://127.0.0.1:8080/health || exit 1
ENTRYPOINT ["/app/app"]
Renforcement de la sécurité
Checklist:
- Exécuter avec un UID/GID non-root
- Système de fichiers en lecture seule; écriture temporaire via tmpfs
- Supprimer toutes les capacités Linux, ne réajouter que l'indispensable
- Activer no-new-privileges pour bloquer l'élévation
- Éviter les namespaces hôte (PID/net) et le mode privileged
- Conserver les secrets en fichiers, pas en variables d'environnement
Exemple docker-compose.yml (défauts sécurité):
version: '3.9'
services:
app:
image: myorg/myapp:1.2.3
user: '10001:10001'
read_only: true
tmpfs:
- /tmp: rw, noexec, nosuid, size=64m
cap_drop:
- ALL
security_opt:
- no-new-privileges: true
restart: always
stop_grace_period: 30s
Secrets en fichiers avec Compose:
services:
app:
secrets:
- source: db_password
target: db_password
mode: 0400
secrets:
db_password:
file: ./secrets/db_password.txt
Votre application doit lire le secret à l'emplacement /run/secrets/db_password.
Limites de ressources et healthchecks
Checklist:
- Ajouter un healthcheck conteneur
- Fixer des limites CPU et mémoire
- Régler les ulimits (nofile, nproc)
- Utiliser une politique de redémarrage adaptée (always ou unless-stopped)
Exemple Compose (hors Swarm):
services:
app:
# Build ou image ici
healthcheck:
test: ['CMD', 'wget', '-q', '-O', '-', 'http://127.0.0.1:8080/health']
interval: 30s
timeout: 3s
retries: 3
start_period: 10s
restart: always
mem_limit: 512m
cpus: '0.50'
ulimits:
nofile:
soft: 65536
hard: 65536
nproc: 4096
Note: deploy.resources est destiné à Swarm. Pour Docker Compose autonome, utilisez mem_limit et cpus comme ci-dessus.
Réseau et ingress
Checklist:
- Un réseau bridge défini par l'utilisateur par application ou domaine
- N'exposer au host que les ports requis
- Garder les services internes privés sur le réseau applicatif
- Terminer TLS sur un proxy d'ingress (par exemple Nginx)
Exemple d'isolation réseau:
services:
app:
networks: [app-net]
nginx:
image: nginx:1.25
depends_on: [app]
ports:
- '80:80'
- '443:443'
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf: ro
networks: [app-net]
networks:
app-net:
driver: bridge
Exemple minimal nginx.conf (upstream):
worker_processes auto;
events { worker_connections 1024; }
http {
upstream app_upstream { server app:8080; }
server {
listen 80;
location / {
proxy_pass http://app_upstream;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
}
}
Journaux et métriques
Checklist:
- Utiliser un driver de logs cohérent avec rotation
- Émettre des logs structurés (JSON lines) côté application
- Capturer CPU, mémoire et compteurs de redémarrage des conteneurs
Exemple de configuration des logs dans Compose:
services:
app:
logging:
driver: json-file
options:
max-size: '10m'
max-file: '3'
Conseils opérationnels:
docker logs --since 10m appdocker stats appdocker inspect --format '{{.State.Health}}' app
Stockage et sauvegardes
Checklist:
- Utiliser des volumes nommés pour l'état
- Garder configuration et secrets hors de l'image
- Documenter et tester la sauvegarde et la restauration
Créer et sauvegarder un volume nommé:
# Créer un volume
docker volume create mydata
# Sauvegarder vers une archive tar datée dans le répertoire courant
docker run --rm \
-v mydata:/data \
-v "$PWD:/backup" \
busybox sh -c 'tar czf /backup/mydata-$(date +%F).tgz -C / data'
# Lister les sauvegardes
ls -lh mydata-*.tgz
# Restaurer depuis une sauvegarde
docker run --rm \
-v mydata:/data \
-v "$PWD:/backup" \
busybox sh -c 'tar xzf /backup/mydata-2026-07-13.tgz -C /'
Pour les bases de données, privilégier les outils natifs (par exemple pg_dump, mysqldump) pour garantir la cohérence.
Mises à niveau et retours arrière
Checklist:
- Épingler les images par version ou digest
- Mettre à jour par petits incréments
- Vérifier l'état et les logs avant le basculement de trafic
- Conserver un chemin de rollback rapide
Épingler par tag et digest dans Compose:
services:
nginx:
image: nginx:1.25.5@sha256: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Rolling upgrade avec deux projets:
# Déployer la prochaine version
docker compose -p myapp-next up -d
# Vérifier la santé
docker compose -p myapp-next ps
# Basculer le trafic à l'ingress (upstream ou DNS)
# Décommissionner la version précédente
docker compose -p myapp-current down
Mise à niveau in-place simple:
docker compose pull
docker compose up -d
docker compose ps
Maintenance et dépannage
Checklist:
- Surveiller l'usage disque et purger prudemment
- Faire tourner les logs et garder des bornes
- Conserver uniquement les images et réseaux nécessaires
Commandes utiles:
# Afficher l'espace utilisé
docker system df
# Lister d'abord les images dangling
docker images -f dangling=true
# Purge sûre (confirmation demandée)
docker image prune
# Purge complète des images inutilisées et du cache de build (attention)
docker image prune -af
# Inspecter les redémarrages récents
docker events --since 1h --filter 'event=restart'
Plan pilote local
Objectif: prouver la checklist sur un service stateless avec des critères d'acceptation clairs.
Périmètre:
- Un service derrière Nginx
- Healthcheck, politique de redémarrage, limites mémoire et CPU
- Rotation des logs via le driver json-file
- Un petit volume nommé et une sauvegarde testée
Étapes:
- Implémenter le fichier Compose avec défauts sécurité, limites et logs
- Ajouter un endpoint de santé et vérifier que
docker psindique healthy - Simuler un crash et vérifier le redémarrage:
docker kill -s SIGKILL app - Capturer les métriques de base avec
docker statset le temps de démarrage - Sauvegarder et restaurer le volume, vérifier l'intégrité des données
Critères d'acceptation:
- Le healthcheck passe en moins de 10 secondes après le démarrage
- Aucun log conteneur ne dépasse 30 Mo après rotation
- Mémoire et CPU restent dans les limites sous une charge basique
- La restauration de sauvegarde recrée l'état attendu
Pièges courants en production et correctifs
- Utiliser des tags :latest
- Correctif: épingler par tags ou digests et mettre à jour intentionnellement.
- Exécuter en root
- Correctif: créer un utilisateur non-root et le définir dans l'image et Compose.
- Oublier les healthchecks
- Correctif: ajouter HEALTHCHECK dans l'image ou Compose.
- Logs non bornés
- Correctif: configurer la rotation json-file ou expédier vers un store central avec rétention.
- Écrire l'état dans le FS du conteneur
- Correctif: utiliser des volumes nommés et vérifier le backup-restore.
- Exposer plus de ports que nécessaire
- Correctif: garder les services internes sur un réseau privé.
- Négliger les ulimits
- Correctif: régler nofile et nproc selon les besoins du workload.
- Compter sur deploy.resources en Compose hors Swarm
- Correctif: utiliser mem_limit et cpus en mode autonome.
Conclusion
Adoptez cette checklist, démarrez par le pilote local, puis étendez service par service. Gardez des changements petits, mesurables et réversibles. Avec des défauts sûrs, des limites claires et des sauvegardes éprouvées, vos Docker operations en production seront plus sûres, plus rapides et plus simples à dépanner. Intégrez ces Docker best practices à votre routine de Docker maintenance pour des déploiements prévisibles et fiables.