DevOpsFacile
AccueilParcours de formationCertificationsModulesCheat SheetÀ Propos
DevOpsFacile

Une plateforme d'apprentissage complète pour maîtriser les pratiques DevOps modernes, du débutant à l'expert.

contact@devopsfacile.fr

Formation

  • Parcours de formation
  • Modules

Informations

  • À Propos
  • Conditions d'utilisation
  • Confidentialité
  • Mentions légales

© 2026 DevOps Facile. Tous droits réservés.

Fait avec pour la communauté DevOps

ModulesDocker Compose et optimisation pour la production08 - Projet Capstone : Stack de production avec Docker Compose et multi-stage builds

Détails

  • 1h
  • Avancé

Objectifs

  • Orchestrer une stack multi-services avec Docker Compose
  • Réduire la taille d'une image avec un multi-stage build
  • Configurer des health checks pour la production
  • Appliquer les bonnes pratiques de sécurité Docker
Module Docker Compose et optimisation pour la production

Exercice 08 : Projet Capstone - Stack de Production avec Docker Compose et Multi-Stage Builds

🎯 Objectifs

À la fin de cet exercice, vous serez capable de :

  • ✅ Rédiger un docker-compose.yml multi-services avec dépendances (depends_on)
  • ✅ Réduire drastiquement la taille d'une image avec un multi-stage build
  • ✅ Configurer des healthcheck pour fiabiliser les démarrages
  • ✅ Appliquer les bonnes pratiques de production : read_only, no-new-privileges, non-root user
  • ✅ Utiliser des variables d'environnement via un fichier .env

Durée estimée : 1h

Difficulté : ⭐⭐⭐⭐⭐ (Expert)

Prérequis :

  • Docker et Docker Compose v2 installés
  • Module Docker Avancé complété (Compose, multi-stage, optimisation, production)
  • Avoir complété les exercices 06 et 07 de ce module

📖 Contexte

Vous allez construire et déployer en local une stack de production complète : une API Node.js avec un multi-stage build, une base de données PostgreSQL, et un reverse proxy Nginx. Tout est orchestré via Docker Compose avec les bonnes pratiques production.


📋 Énoncé

Rédigez un docker-compose.yml production-ready pour une stack Nginx + API Node.js + PostgreSQL, en utilisant un multi-stage Dockerfile pour l'API.


🧭 Déroulement de l'exercice

Tâche 1 : Créer l'application Node.js

Créez node-api/ contenant une application Express.js minimale avec une route /health et une route / retournant un JSON. Ajoutez un package.json avec Express comme dépendance.

Indice : server.js avec express(), .get('/', ...), .listen(3000). Le package.json doit avoir "start": "node server.js".

Vérification : L'arborescence contient node-api/server.js et node-api/package.json.


Tâche 2 : Écrire le multi-stage Dockerfile

Créez node-api/Dockerfile avec deux stages :

  1. Stage builder (node:20-alpine) : installe toutes les dépendances (npm ci) y compris dev
  2. Stage production (node:20-alpine) : copie uniquement node_modules et server.js du builder, crée un utilisateur node, expose le port 3000

Indice : FROM node:20-alpine AS builder pour le premier stage, FROM node:20-alpine AS production pour le second. COPY --from=builder /app/node_modules ./node_modules copie depuis le stage builder.

Vérification : docker build -t node-api:prod --target production node-api/ réussit. La taille de l'image est inférieure à 100 MB.


Tâche 3 : Configurer Nginx comme reverse proxy

Créez nginx/nginx.conf pour rediriger les requêtes HTTP port 80 vers api:3000. Nginx doit servir de point d'entrée unique.

Indice : upstream api { server api:3000; } et location / { proxy_pass http://api; }. Dans Docker Compose, les services se joignent par leur nom de service.

Vérification : Le fichier nginx/nginx.conf contient proxy_pass vers le service api.


Tâche 4 : Rédiger le docker-compose.yml

Créez docker-compose.yml à la racine du projet avec les 3 services :

  • db : PostgreSQL 16-alpine, volume nommé, variables d'env via .env, healthcheck sur pg_isready
  • api : build depuis node-api/, dépend de db (condition : service_healthy), variables d'env
  • nginx : image nginx:1.25-alpine, monte nginx/nginx.conf, expose le port 80, dépend de api

Indice : La clé healthcheck s'écrit sous le service. depends_on: avec condition: service_healthy attend que le healthcheck passe avant de démarrer le service dépendant.

Vérification : docker compose config valide la syntaxe sans erreur.


Tâche 5 : Lancer et vérifier la stack

Créez un fichier .env avec les variables PostgreSQL. Lancez la stack avec docker compose up -d, attendez que les services soient healthy, et vérifiez que l'API répond à travers Nginx.

Indice : docker compose up -d --build reconstruit les images et démarre. docker compose ps montre l'état. docker compose logs -f api suit les logs de l'API.

Vérification : curl http://localhost:80/health retourne {"status": "ok"}.


Tâche 6 : Appliquer les contraintes de sécurité production

Ajoutez dans docker-compose.yml pour les services api et nginx :

  • security_opt: ["no-new-privileges:true"]
  • Vérifiez que l'API tourne en utilisateur non-root avec docker compose exec api whoami

Indice : security_opt est une liste YAML sous le service. no-new-privileges:true empêche un processus d'escalader ses privilèges via setuid.

Vérification : docker compose exec api whoami retourne node (pas root). docker compose exec nginx whoami retourne nginx.


🗂️ Mini-Projet : Stack complète production-ready

Arborescence finale :

projet-docker-avance/
├── .env
├── docker-compose.yml
├── node-api/
│   ├── server.js
│   ├── package.json
│   └── Dockerfile
└── nginx/
    └── nginx.conf

Déploiement en une commande :

bash
# Lancer toute la stack
docker compose up -d --build

# Vérifier l'état des health checks
docker compose ps

# Test bout en bout
curl http://localhost/
curl http://localhost/health

# Taille de l'image multi-stage
docker images node-api:prod

# Logs
docker compose logs --tail=20

Checkpoints de validation :

  • docker compose config valide sans erreur
  • docker compose ps affiche les 3 services running (healthy) ou Up
  • curl http://localhost/health retourne {"status": "ok"}
  • docker images node-api:prod --format "{{.Size}}" - image inférieure à 100 MB
  • docker compose exec api whoami retourne node (non-root)
  • docker compose down -v supprime les conteneurs et volumes proprement

Retour au module

Sur cette page

  • 🎯 Objectifs
  • 📖 Contexte
  • 📋 Énoncé
  • 🧭 Déroulement de l'exercice
  • Tâche 1 : Créer l'application Node.js
  • Tâche 2 : Écrire le multi-stage Dockerfile
  • Tâche 3 : Configurer Nginx comme reverse proxy
  • Tâche 4 : Rédiger le docker-compose.yml
  • Tâche 5 : Lancer et vérifier la stack
  • Tâche 6 : Appliquer les contraintes de sécurité production
  • 🗂️ Mini-Projet : Stack complète production-ready