
Orchestration de conteneurs avec Docker Compose (pour le développement et les tests)
Apprenez à utiliser Docker Compose pour définir et gérer facilement des applications multi-conteneurs (ex: Spring Boot + base de données) en environnement de développement et de test.
Introduction : Gérer plusieurs conteneurs simplement
Lorsque l'on développe ou teste une application Spring Boot, elle interagit souvent avec d'autres services : une base de données, un cache (Redis), un broker de messages (Kafka, RabbitMQ), etc. Gérer manuellement le démarrage, l'arrêt, la configuration réseau et la liaison de plusieurs conteneurs Docker distincts pour recréer cet environnement peut vite devenir fastidieux et source d'erreurs.
C'est là qu'intervient Docker Compose. C'est un outil fourni par Docker spécifiquement conçu pour définir et exécuter des applications multi-conteneurs. Avec un unique fichier de configuration YAML (typiquement `docker-compose.yml`), vous décrivez l'ensemble des services qui composent votre application, leurs images, leurs configurations (ports, variables d'environnement, volumes) et leurs dépendances.
Docker Compose simplifie radicalement la gestion d'environnements locaux complexes. D'une seule commande (`docker-compose up`), vous pouvez démarrer tous les services nécessaires configurés pour communiquer entre eux. Il est particulièrement précieux pour les environnements de développement et pour l'exécution de tests d'intégration qui nécessitent des dépendances externes sous forme de conteneurs.
Le fichier `docker-compose.yml` : Définir votre stack
La pièce maîtresse de Docker Compose est le fichier `docker-compose.yml`. Il utilise la syntaxe YAML pour décrire la structure de votre application multi-conteneurs. Les concepts clés sont :
- `version` : Définit la version de la syntaxe du fichier Compose (ex: `'3.8'`, `'3.9'`).
- `services` : La section principale où chaque sous-élément définit un conteneur individuel (un 'service'). Le nom du sous-élément devient le nom d'hôte du service sur le réseau interne créé par Compose.
- `image` : Spécifie l'image Docker à utiliser pour le service (ex: `postgres:15-alpine`, `redis:latest`).
- `build` : Alternativement à `image`, vous pouvez indiquer un chemin vers un répertoire contenant un `Dockerfile` pour construire l'image localement.
- `ports` : Mappe les ports entre l'hôte et le conteneur (ex: `"8080:8080"`).
- `environment` : Permet de définir des variables d'environnement à l'intérieur du conteneur (très utilisé pour la configuration, comme les identifiants de base de données).
- `volumes` : Définit des volumes pour persister des données en dehors du cycle de vie du conteneur (essentiel pour les bases de données) ou pour monter du code source local dans le conteneur.
- `networks` : Permet de définir des réseaux personnalisés. Par défaut, Compose crée un réseau unique pour tous les services du fichier, leur permettant de communiquer en utilisant leurs noms de service comme noms d'hôte.
- `depends_on` : Permet de spécifier des dépendances entre services. Compose démarrera les dépendances avant le service dépendant. Attention : Cela ne garantit que le démarrage du conteneur, pas que le service à l'intérieur soit prêt à accepter des connexions (ex: la base de données peut encore être en train d'initialiser). Des mécanismes de 'healthcheck' ou des scripts d'attente sont souvent nécessaires pour une synchronisation plus fine.
Exemple : Application Spring Boot avec PostgreSQL
Imaginons une application Spring Boot (`mon-app`) qui nécessite une base de données PostgreSQL. Voici à quoi pourrait ressembler un fichier `docker-compose.yml` simple :
version: '3.8'
services:
# Service pour la base de données PostgreSQL
db:
image: postgres:15-alpine
container_name: ma_base_postgres # Nom optionnel du conteneur
environment:
POSTGRES_DB: madb # Nom de la base de données à créer
POSTGRES_USER: monuser # Nom d'utilisateur
POSTGRES_PASSWORD: monmotdepasse # Mot de passe
volumes:
- postgres_data:/var/lib/postgresql/data # Volume pour persister les données
ports:
- "5432:5432" # Expose le port PostgreSQL sur l'hôte (optionnel, pour accès externe)
networks:
- app-network
# Service pour l'application Spring Boot
app:
# Supposons qu'une image 'mon-app-image:latest' a déjà été construite
image: mon-app-image:latest
# OU: Construire depuis le Dockerfile local
# build: .
container_name: mon_app_spring
environment:
# Configuration pour se connecter à la base de données
# Note: 'db' est le nom d'hôte du service PostgreSQL sur le réseau Compose
SPRING_DATASOURCE_URL: jdbc:postgresql://db:5432/madb
SPRING_DATASOURCE_USERNAME: monuser
SPRING_DATASOURCE_PASSWORD: monmotdepasse
SPRING_JPA_HIBERNATE_DDL_AUTO: update # Ou 'validate', 'create', etc.
# Autres variables d'environnement si nécessaire
SPRING_PROFILES_ACTIVE: docker
ports:
- "8080:8080" # Expose le port de l'application Spring Boot
depends_on:
- db # Indique que 'app' dépend de 'db'
networks:
- app-network
# Définition des volumes nommés
volumes:
postgres_data:
# Définition des réseaux
networks:
app-network:
driver: bridge
Dans cet exemple, l'application Spring Boot (`app`) peut se connecter à la base de données en utilisant l'URL `jdbc:postgresql://db:5432/madb`, car `db` est le nom d'hôte résolvable du service PostgreSQL sur le réseau `app-network` créé par Docker Compose.
Commandes et flux de travail courants
Une fois votre fichier `docker-compose.yml` créé, vous interagissez avec votre stack d'application via la commande `docker-compose` (ou `docker compose` dans les versions plus récentes de Docker) dans le répertoire contenant le fichier :
- `docker-compose up` : Crée et démarre tous les services définis dans le fichier. Affiche les logs agrégés de tous les conteneurs dans le terminal. Utilisez `Ctrl+C` pour arrêter.
- `docker-compose up -d` : Démarre les services en arrière-plan ('detached mode').
- `docker-compose down` : Arrête et supprime les conteneurs, ainsi que le réseau par défaut. Les données dans les volumes nommés (comme `postgres_data`) persistent.
- `docker-compose down -v` : Idem que `down`, mais supprime également les volumes nommés définis dans le fichier Compose. Utile pour repartir de zéro.
- `docker-compose ps` : Liste les conteneurs gérés par Compose pour ce projet et leur état.
- `docker-compose logs` : Affiche les logs des services.
- `docker-compose logs -f [nom_service]` : Affiche les logs en continu (follow), éventuellement pour un service spécifique.
- `docker-compose build [nom_service]` : Construit ou reconstruit l'image d'un ou de tous les services définis avec l'instruction `build:`.
- `docker-compose exec
Exécute une commande à l'intérieur d'un conteneur déjà en cours d'exécution (ex: `docker-compose exec db psql -U monuser -d madb` pour ouvrir un shell psql).` : - `docker-compose restart [nom_service]` : Redémarre un ou tous les services.
Le flux de travail typique en développement consiste à démarrer la stack avec `docker-compose up -d`, coder sur l'application, potentiellement reconstruire l'image de l'application (`docker-compose build app`) puis redémarrer le service (`docker-compose restart app`) ou relancer la stack (`docker-compose down && docker-compose up -d`) après des modifications. Pour les tests d'intégration dans un pipeline CI/CD, on démarre la stack, on lance les tests, puis on la détruit avec `docker-compose down -v`.
Docker Compose : Idéal pour le dev/test, pas l'orchestration de production
Docker Compose excelle dans la simplification de la gestion d'environnements multi-conteneurs sur une unique machine hôte. Il est parfait pour s'assurer que tous les développeurs d'une équipe travaillent avec le même ensemble de dépendances ou pour fournir les services nécessaires à l'exécution des tests d'intégration.
Cependant, Docker Compose n'est généralement pas considéré comme un outil d'orchestration suffisant pour des déploiements en production complexes et à grande échelle. Il lui manque nativement des fonctionnalités cruciales offertes par des orchestrateurs comme Kubernetes :
- Gestion multi-hôtes (clustering) : Compose est conçu pour un seul Docker Engine.
- Haute disponibilité et auto-réparation (self-healing) : Il ne redémarre pas automatiquement les conteneurs sur d'autres machines si un hôte tombe en panne.
- Mise à l'échelle avancée et load balancing : Bien qu'on puisse définir plusieurs instances (`scale`), la répartition de charge et la découverte de services sont basiques comparées à Kubernetes.
- Déploiements sans interruption (rolling updates) : Moins trivial à mettre en oeuvre qu'avec Kubernetes.
- Gestion avancée du réseau et de la sécurité : Kubernetes offre des politiques réseau et une gestion des secrets plus sophistiquées.
En conclusion, Docker Compose est un outil indispensable dans la boîte à outils du développeur Spring Boot travaillant avec des conteneurs. Il rend les environnements de développement et de test reproductibles et faciles à gérer, mais pour l'orchestration en production, des solutions plus robustes comme Kubernetes sont généralement préférées.