TP6 : Composer des stacks multi-services avec Docker Compose
Objectif du TP
- Décrire et lancer plusieurs services connectés via un fichier
docker-compose.yml(app + reverse proxy). - Manipuler
docker compose up/down/logs/pset la gestion des volumes/réseaux.
Rendu attendu
- Fichiers produits (
index.js,Dockerfile,default.conf,docker-compose.yml). - Capture du rendu « Hello from Node.js! » via Nginx.
Questions d'ouverture
- Qu’est-ce qu’un “service” dans Compose par rapport à un simple
docker run? - Comment Compose gère-t-il les réseaux/volumes entre services ?
Focus : Compose en pratique
Compose permet de décrire les services, réseaux et volumes dans un YAML unique.
- docker compose (ou
docker-compose) permet de décrire des services, réseaux et volumes dans un fichier YAML. - On lance le tout par
docker compose up -d. - Une application peut comporter une base de données, un backend et un frontend.
- But de Docker Compose : Lancer, connecter et gérer tous ces services en une seule commande, avec gestion automatique des volumes et réseaux.
Concepts clés
- Services : Chaque service dans
docker-compose.ymlcorrespond à un conteneur. - Volumes : Permettent de persister ou de partager des données entre services.
- Réseaux : Docker Compose crée automatiquement un réseau pour les services, mais vous pouvez définir des réseaux personnalisés.
depends_on: Définit l’ordre de démarrage des services, mais ne garantit pas qu’un service soit prêt à être utilisé (exemple : une base de données peut prendre du temps à démarrer).
Attention -
depends_onne fait qu’orchestrer l’ordre de lancement. Pour attendre qu’un service soit prêt, utilisez unhealthchecket faites en sorte que l’app cliente vérifie la disponibilité (ex. retry côté app) ou un script d’attente.
Tour d’horizon des outils de gestion multi-conteneurs
- Docker Compose: pour gérer des services locaux ou des stacks simples.
- Docker Swarm: orchestration intégrée à Docker, utile pour des environnements distribués simples.
- Kubernetes: orchestrateur avancé, mais plus complexe à mettre en place.
Mise en pratique
Manipuler une stack de services avec Docker Compose
Tableau récapitulatif des commandes courantes docker compose :
| Commande | Description |
|---|---|
docker compose up -d |
Crée et démarre la stack en arrière-plan |
docker compose up --build -d |
Reconstruit les images puis démarre la stack |
docker compose down |
Arrête la stack et supprime conteneurs + réseau par défaut |
docker compose down -v |
Idem, et supprime aussi les volumes nommés (attention) |
docker compose stop |
Arrête les conteneurs sans les supprimer |
docker compose start |
Démarre des conteneurs arrêtés |
docker compose restart [SERVICE] |
Redémarre un service (ou tous si non précisé) |
docker compose ps |
Liste l’état des conteneurs de la stack |
docker compose logs -f [SERVICE] |
Affiche/suit les logs (éventuellement d’un service ciblé) |
docker compose build [--no-cache] |
Construit les images définies dans le compose |
docker compose pull |
Récupère les images depuis un registre |
docker compose exec SERVICE sh -c "…" |
Exécute une commande dans un conteneur en cours d’exécution |
docker compose ls |
Liste les projets Compose présents sur la machine |
docker compose rm |
Supprime des conteneurs arrêtés de la stack |
Gérer volumes et réseaux avec Docker Compose
-
Définir des volumes nommés dans le fichier
docker-compose.yml: -
Les utiliser dans un service :
- Créer un réseau personnalisé :
- Et l’associer à un service :
Exemple
services:
db:
# Image MariaDB supportant amd64 & arm64
image: mariadb:10.6.4-focal
# Si vous préférez MySQL, utilisez une version récente compatible arm64 si besoin
#image: mysql:8
command: '--default-authentication-plugin=mysql_native_password'
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
- MYSQL_ROOT_PASSWORD=somewordpress
- MYSQL_DATABASE=wordpress
- MYSQL_USER=wordpress
- MYSQL_PASSWORD=wordpress
expose:
- 3306
- 33060
wordpress:
image: wordpress:latest
volumes:
- wp_data:/var/www/html
ports:
- 80:80
restart: always
environment:
- WORDPRESS_DB_HOST=db
- WORDPRESS_DB_USER=wordpress
- WORDPRESS_DB_PASSWORD=wordpress
- WORDPRESS_DB_NAME=wordpress
volumes:
db_data:
wp_data:
Construire une stack multi-services (Node.js + reverse proxy Nginx)
L’objectif de cet exercice est de créer une stack comprenant deux services : 1. Un backend Node.js. 2. Un reverse proxy Nginx.
Objectifs : - Mettre en place un service Node.js comme backend. - Configurer un reverse proxy Nginx pour rediriger les requêtes vers le backend. - Gérer les deux services via Docker Compose.
1. Préparer l’application Node.js
- Créer le fichier
index.js:
const http = require('http');
const port = 3000;
const requestListener = (req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Hello from Node.js!');
};
const server = http.createServer(requestListener);
server.listen(port, () => {
console.log(`Server running on port ${port}`);
});
2. Créer le fichier Dockerfile pour Node.js
3. Préparer la configuration Nginx
- Créer le fichier
default.conf(configuration du reverse proxy) :
- Cette configuration redirige toutes les requêtes reçues sur le port 80 vers le service
app(Node.js) sur le port 3000.
4. Créer le fichier docker-compose.yml
version: "3.8"
services:
app:
build:
context: .
dockerfile: Dockerfile
container_name: app
networks:
- mynet
proxy:
image: nginx:alpine
container_name: proxy
volumes:
- ./default.conf:/etc/nginx/conf.d/default.conf:ro
ports:
- "80:80"
depends_on:
- app
networks:
- mynet
networks:
mynet:
- app : Le backend Node.js.
- proxy : Le reverse proxy Nginx.
- depends_on : Assure que
appest lancé avantproxy(mais pas forcément prêt). - mynet : Réseau personnalisé permettant aux deux services de communiquer.
5. Lancer et tester la stack
- Lancer la stack :
- Vérifier l’état :
- Tester dans un navigateur :
- Accédez à http://localhost.
- Vous devriez voir Hello from Node.js!.
6. Nettoyer
- Arrêter et supprimer la stack :
- Supprimer les images locales non utilisées :
Conclusion
- Vous avez décrit et lancé une mini-stack (Node.js + Nginx) avec Docker Compose.
- Vous comprenez le rôle de
depends_onet l’intérêt des healthchecks.