Tu sais builder des images, orchestrer des services avec Compose, gérer les volumes et les réseaux. Mais entre un docker compose up sur ta machine et une app qui tourne en production sans te réveiller à 3h du matin, il y a un gouffre. Ce chapitre te donne les clés pour le franchir : scanner tes images avant qu’elles partent en prod, monitorer ce qui tourne, et appliquer une checklist de déploiement béton.
Pourquoi le déploiement Docker mérite un chapitre entier
En développement, Docker te simplifie la vie. En production, Docker peut te la ruiner si tu ne fais pas les choses correctement. Une image avec une CVE critique, un conteneur sans limite mémoire qui OOM-kill ton hôte, un service sans health check que personne ne détecte comme mort — chacun de ces scénarios arrive tous les jours en entreprise.
🔥 Cas réel : En 2024, une startup fintech a déployé une image Node.js en prod sans scan de sécurité. L’image de base contenait une vulnérabilité OpenSSL critique (CVE connue depuis 3 mois). Un attaquant a exploité la faille pour accéder aux données clients. Un simple trivy image avant le déploiement aurait bloqué le push.
Le déploiement Docker, c’est trois piliers : sécurité (scanner avant de shipper), observabilité (savoir ce qui se passe en prod), et discipline (appliquer systématiquement les bonnes pratiques).
Comprendre le pipeline de déploiement sécurisé
Le principe est simple : ton code passe par un pipeline CI/CD qui build l’image, la scanne, et ne la déploie que si elle passe les contrôles. Voici le flux :
- Build — Le CI construit l’image Docker à partir du Dockerfile
- Scan — Trivy analyse l’image pour détecter les vulnérabilités connues (CVE)
- Test — Les tests applicatifs tournent dans un conteneur éphémère
- Push — L’image validée est poussée vers un registry (Docker Hub, GHCR, ECR…)
- Deploy — L’image est tirée en prod, avec limites de ressources, health checks et monitoring
💡 Tip DevOps : Épingle toujours tes images de base par digest SHA256, pas par tag. Un tag latest ou même 22-alpine peut pointer vers une image différente d’un jour à l’autre. Le digest garantit la reproductibilité.
⚠️ Attention : Ne confonds pas “l’image build en local” et “l’image qui tourne en prod”. Sans registry et sans pipeline, tu n’as aucune garantie que ce qui tourne en prod correspond à ce que tu as testé.
Commandes essentielles
Scanner une image avec Trivy — Trivy est l’outil open-source de référence pour détecter les vulnérabilités dans les images Docker. Avant de pousser quoi que ce soit en prod, scanne systématiquement :
# Scanner une image et afficher toutes les vulnérabilités
trivy image mon-api:latest
# Ne montrer que les HIGH et CRITICAL
trivy image --severity HIGH,CRITICAL mon-api:latest
# Faire échouer le pipeline CI si une CRITICAL est trouvée
trivy image --exit-code 1 --severity CRITICAL mon-api:latest
Intégrer le scan dans GitHub Actions — Ce workflow se déclenche à chaque push sur main. Si Trivy trouve une vulnérabilité critique, le pipeline échoue et le déploiement est bloqué :
# .github/workflows/security.yml
name: Build & Scan
on:
push:
branches: [main]
jobs:
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build
run: docker build -t mon-api:${{ github.sha }} .
- name: Trivy scan
uses: aquasecurity/trivy-action@master
with:
image-ref: mon-api:${{ github.sha }}
exit-code: 1
severity: CRITICAL,HIGH
Monitorer les conteneurs en prod — docker stats c’est bien pour un coup d’œil, mais en prod tu veux des métriques historisées. cAdvisor + Prometheus + Grafana, c’est le trio classique :
# docker-compose.monitoring.yml
services:
cadvisor:
image: gcr.io/cadvisor/cadvisor:latest
volumes:
- /:/rootfs:ro
- /var/run:/var/run:ro
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
ports:
- "8080:8080"
deploy:
resources:
limits:
memory: 128M
prometheus:
image: prom/prometheus:latest
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
ports:
- "9090:9090"
grafana:
image: grafana/grafana:latest
ports:
- "3000:3000"
Activer les métriques Docker — Pour que Prometheus puisse scraper le daemon Docker lui-même, active l’endpoint de métriques :
{
"metrics-addr": "0.0.0.0:9323",
"experimental": true
}
Appliquer la checklist production dans un Dockerfile — Ce multi-stage build applique les bonnes pratiques : image Alpine, user non-root, npm ci pour des builds reproductibles, et séparation build/runtime :
FROM node:22-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM node:22-alpine
WORKDIR /app
RUN addgroup -S app && adduser -S app -G app
COPY --from=builder --chown=app:app /app/dist ./dist
COPY --from=builder --chown=app:app /app/node_modules ./node_modules
COPY --from=builder --chown=app:app /app/package.json ./
USER app
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=3s \
CMD wget -qO- http://localhost:3000/health || exit 1
CMD ["node", "dist/server.js"]
🧠 À retenir : La checklist production Docker tient en 10 points : user non-root, image Alpine/distroless, multi-stage build, no-new-privileges, filesystem read-only, cap_drop: ALL, limites CPU/mémoire, health checks, rotation des logs, secrets (jamais en variable d’env).
Cas concret : déployer une API en production
Imagine que tu bosses dans une boîte e-commerce. L’équipe dev te livre une API Node.js pour le catalogue produits. Ton job : la mettre en prod proprement.
Étape 1 — Tu reçois le Dockerfile du dev : image node:22 complète (900 Mo), npm install, mot de passe en dur dans ENV, pas de health check. Classique.
Étape 2 — Tu appliques la checklist : tu passes sur Alpine, tu ajoutes un multi-stage build, tu vires le mot de passe pour utiliser Docker Secrets, tu ajoutes un user non-root et un health check. L’image passe de 900 Mo à 180 Mo.
Étape 3 — Tu configures le Compose de prod avec les limites et le monitoring :
services:
api-catalogue:
image: registry.company.com/api-catalogue:v2.1.0
user: "1000:1000"
read_only: true
security_opt:
- no-new-privileges:true
deploy:
resources:
limits:
memory: 256M
cpus: "0.5"
healthcheck:
test: ["CMD", "wget", "-qO-", "http://localhost:3000/health"]
interval: 30s
retries: 3
restart: unless-stopped
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
Étape 4 — Tu mets Trivy dans la CI : chaque merge request déclenche un scan. Si une CVE critique est détectée, le merge est bloqué. L’équipe dev reçoit le rapport et met à jour l’image de base.
🔥 Cas réel : Ce workflow (scan CI + checklist prod + monitoring) est exactement celui utilisé par des boîtes comme GitLab, Datadog ou Shopify pour leurs déploiements Docker internes.
Pièges fréquents
Scanner en local mais pas en CI — Tu scannes sur ta machine, tout est clean. Mais le CI build avec un cache différent, et l’image en prod contient des vulnérabilités que tu n’as jamais vues. Le scan doit être dans le pipeline, pas dans ta tête.
Confondre monitoring et alerting — Avoir Grafana avec de jolis dashboards ne sert à rien si personne ne regarde. Configure des alertes : CPU > 80% pendant 5 min, mémoire > 90%, health check en échec. Un dashboard sans alerte, c’est de la décoration.
⚠️ Attention : Ne mets jamais restart: always sans health check. Un conteneur qui crash-loop sera redémarré indéfiniment sans que personne ne soit alerté. Utilise restart: unless-stopped couplé à un health check et une alerte.
Oublier le .dockerignore — Sans lui, tu embarques .git, node_modules, .env et potentiellement des secrets dans ton image. Crée-le systématiquement avec au minimum : .git, node_modules, .env, *.md, docker-compose*.yml.
Déployer avec latest — En prod, chaque déploiement doit pointer vers une version précise (tag semver ou SHA du commit). latest est un alias mouvant qui rend le rollback impossible.
💡 Tip DevOps : Tague tes images avec le SHA du commit Git (mon-api:abc1234). Tu sais exactement quel code tourne en prod, et le rollback se fait en une ligne : docker compose pull && docker compose up -d.
Exercice : sécuriser et déployer
Prends ce Dockerfile volontairement mal fichu et transforme-le en version production :
FROM node:22
WORKDIR /app
COPY . .
RUN npm install
ENV DB_PASSWORD=monsecret123
EXPOSE 3000
CMD ["node", "server.js"]
Ta mission :
- Passe sur
node:22-alpineavec un multi-stage build - Remplace
npm installparnpm ci - Ajoute un user non-root
- Supprime le mot de passe en dur — utilise un Docker Secret
- Ajoute un health check
- Crée un
.dockerignorecomplet - Scanne ton image avec
trivy imageet corrige jusqu’à zéro CRITICAL - Écris le
docker-compose.ymlde prod avec limites, health check, restart policy et logging
À retenir
🧠 Les 3 piliers du déploiement Docker :
- Sécurité — Trivy en CI, zéro CRITICAL avant de déployer, images épinglées par digest
- Observabilité — cAdvisor + Prometheus + Grafana, avec des alertes configurées (pas juste des dashboards)
- Discipline — Checklist production appliquée systématiquement : user non-root, limites, health checks, secrets, logs rotatés
Le déploiement Docker en production n’est pas compliqué — c’est méthodique. Applique la checklist à chaque service, automatise les scans en CI, et monitore ce qui tourne. Tu dormiras mieux.
➡️ La suite : Tu maîtrises maintenant Docker de A à Z. Direction Kubernetes pour passer à l’orchestration à grande échelle — parce qu’un seul serveur, c’est bien, mais un cluster, c’est mieux !
🖥️ Pratique sur ton propre serveur
Pour suivre Apprendre Docker en conditions réelles, tu as besoin d'un VPS. DigitalOcean offre 200$ de crédit gratuit pour démarrer.
Contenu réservé aux abonnés
Ce chapitre fait partie de la formation complète. Abonne-toi pour débloquer tous les contenus.
Débloquer pour 29 CHF/moisLe chapitre 1 de chaque formation est gratuit.
Série pas encore débloquée
Termine la série prérequise d'abord pour accéder à ce contenu.
Aller à la série prérequiseSérie : Apprendre Docker
8 / 10- Pourquoi Docker ? Les conteneurs expliqués
- Tes premières commandes Docker
- Ton premier Dockerfile
- Dockerfile avancé : multi-stage et optimisation
- Docker Compose : orchestrer tes services
- Compose avancé : volumes, réseaux et scaling
- Docker en production : logs et healthchecks
- 8 Déploiement et CI/CD avec Docker
- 9 Sécurité Docker : rootless et isolation
- 10 Scanning et conformité Docker
Sur cette page
Articles liés
Pourquoi Docker ? Les conteneurs expliqués
Découvre ce que sont les conteneurs, comment ils se distinguent des machines virtuelles et comprends l'architecture Docker.
Tes premières commandes Docker
Prends en main Docker avec tes premières commandes : docker run, pull, ps, images, exec et le cycle de vie des conteneurs.
Ton premier Dockerfile
Apprends à écrire un Dockerfile avec les instructions essentielles : FROM, COPY, RUN, CMD et docker build.