if [ -f compose.yml ]; then
docker compose up --detach
else
echo "(skipped: no compose.yml in $(pwd))"
fi(skipped: no compose.yml in /workdir/Content)
Principes de base de l’Orchestration de conteneurs, application avec Docker Compose.
L’orchestration consiste à coordonner plusieurs conteneurs au sein d’une même application. Si kubernetes de Google est l’outil de référence pour les déploiements complexes, docker compose offre une alternative plus simple pour les architectures modestes.
Docker compose, disponible comme plugin de Docker, permet de décrire une architecture multi-conteneurs dans un fichier YAML (docker-compose.yml). Il gère les services, volumes et réseaux avec la même syntaxe que Docker, simplifiant ainsi le déploiement d’applications conteneurisées.
compose.yml) pour définir les services, réseaux et volumes.Les exemples suivants sont accessibles dans le dépôt :
✅ : ebpro/sample-containers-java-restjpa
/home/jovyan/work/github/ebpro/sample-containers-java-restjpaClone Command:
git clone -b develop https://github.com/ebpro/sample-containers-java-restjpaMissing docker-compose.yml in /home/jovyan/work/github/ebpro/sample-containers-java-restjpa (clone failed?) exit Restarting Bash
docker-compose.yml ou compose.yml.compose.yml (ou docker-compose.yml) s’articule autour de quatre piliers principaux.
services : C’est le cœur du fichier. Chaque service définit comment instancier un conteneur (image, build, variables d’environnement, dépendances).networks : Définit les ponts de communication. Par défaut, Compose crée un réseau pour le projet, mais vous pouvez isoler (ex: frontend vs backend).volumes : Déclare les espaces de stockage qui survivent à la suppression des conteneurs (docker compose down).configs / secrets : Permet de monter des fichiers de configuration ou des données sensibles de manière sécurisée (souvent utilisé avec Swarm ou les versions récentes de Compose).services: # 1. Les conteneurs à lancer
web:
build: .
ports: ["80:80"]
networks: [frontend]
volumes: [data:/var/www/html]
networks: # 2. Les réseaux (isolations logiques)
frontend:
volumes: # 3. Le stockage persistant
data:
configs/secrets: # 4. Données de config et mots de passeUn service dans Docker Compose correspond à un conteneur Docker. Chaque service peut spécifier une image Docker à utiliser ou un contexte de construction pour créer l’image. Les services peuvent également définir des variables d’environnement, des ports exposés, des volumes montés, et des dépendances entre eux.
docker-compose.yml
Pour démarrer une application multi-conteneurs, utilisez la commande docker compose up dans le répertoire contenant le fichier docker-compose.yml. L’option -d (detach) permet d’exécuter les conteneurs en arrière-plan :
if [ -f compose.yml ]; then
docker compose up --detach
else
echo "(skipped: no compose.yml in $(pwd))"
fi(skipped: no compose.yml in /workdir/Content)
La commande docker compose ls fournit une vue d’ensemble de tous les projets Docker Compose en cours d’exécution, affichant pour chacun son nom, le répertoire source, l’état des services et le nombre de conteneurs actifs.
docker compose lsNAME STATUS CONFIG FILES
La commande docker compose ps affiche les conteneurs du projet en cours, avec leurs noms générés automatiquement selon le format <projet>-<service>-<numéro>. Cette convention de nommage permet d’exécuter plusieurs instances du même projet dans différents répertoires ou de dupliquer des services sans conflits, à condition d’éviter les liaisons de volumes (bind mounts) et les mappages de ports fixes vers l’hôte.
if [ -f compose.yml ] || [ -f compose.prod.yml ]; then
docker compose ps
else
echo "(skipped: no compose project in $(pwd))"
fi(skipped: no compose project in /workdir/Content)
Docker Compose gère automatiquement les réseaux et volumes en les préfixant avec le nom du projet (par défaut, le nom du répertoire parent), permettant ainsi d’isoler les ressources entre différents projets et d’éviter les conflits de nommage, tout en facilitant leur identification et leur gestion avec des commandes comme docker compose down -v pour le nettoyage complet.
docker network lsNETWORK ID NAME DRIVER SCOPE
b3cc13802456 app-net bridge local
f263eadfd226 bridge bridge local
46fbfbaa3d92 host host local
2df717f346bf none null local
docker volume lsDRIVER VOLUME NAME
local 27ff366c94ac2c841873728f80f21d6947b67b578f23fdf302d6590ae077310d
local tp0-www
La commande docker compose logs permet de visualiser les journaux d’un ou plusieurs services, avec des options utiles comme -f pour suivre les logs en temps réel, --tail pour limiter le nombre de lignes affichées, et --since pour filtrer par date, facilitant ainsi le diagnostic et la surveillance des applications multi-conteneurs.
if [ -f compose.yml ]; then
docker compose logs --tail 5
else
echo "(skipped: no compose.yml in $(pwd))"
fi(skipped: no compose.yml in /workdir/Content)
Docker Compose offre plusieurs commandes pour gérer le cycle de vie des services : stop pour arrêter les conteneurs, rm pour les supprimer, restart pour les redémarrer, et down pour tout nettoyer (conteneurs et réseaux) - avec l’option -v pour inclure également la suppression des volumes, qu’ils soient nommés ou anonymes.
La commande docker compose down -v supprime définitivement toutes les données persistées dans les volumes.
if [ -f compose.yml ]; then
docker compose down -v
else
echo "(skipped: no compose.yml in $(pwd))"
fi(skipped: no compose.yml in /workdir/Content)
L’autre service app est une application JPA/REST Java dont l’image docker est produite par sample-java/restjpa/Dockerfile.
L’option build dans docker-compose.yml indique qu’il faut fabriquer l’image à partir du contexte courant (image sera alors son tag).
La sous-commande build de Docker Compose permet de construire les images à partir du contexte défini dans le fichier docker-compose.yml.
if [ -f compose.yml ]; then
docker compose build
else
echo "(skipped: no compose.yml in $(pwd))"
fi(skipped: no compose.yml in /workdir/Content)
Il est aussi une sous-commande push pour pousser les images vers un registre (Docker Hub, GitHub Container Registry, …).
La fabrication de l’image sera automatique au démarrage au besoin avec up uniquement si l’image n’existe pas déjà localement ou si le Dockerfile a été modifié depuis la dernière construction. Pour forcer la reconstruction de l’image à chaque démarrage, utilisez l’option --build avec docker compose up.
if [ -f compose.yml ]; then
docker compose up --detach
else
echo "(skipped: no compose.yml in $(pwd))"
fi(skipped: no compose.yml in /workdir/Content)
La directive depends_on dans Docker Compose permet de gérer les dépendances entre services, mais va au-delà du simple ordre de démarrage grâce à la condition service_healthy qui, combinée avec des HEALTHCHECK (cf. Dockerfile), assure qu’un service est réellement opérationnel avant le démarrage des services qui en dépendent - par exemple, vérifier qu’une base de données accepte effectivement les connexions avant de lancer l’application qui l’utilise.
Les exemples suivants sont accessibles dans le dépôt :
✅ : ebpro/notebook-java-rest-sample-quarkus
/home/jovyan/work/github/ebpro/notebook-java-rest-sample-quarkusClone Command:
git clone -b develop https://github.com/ebpro/notebook-java-rest-sample-quarkusProjet de demo : /home/jovyan/work/github/ebpro/notebook-java-rest-sample-quarkus
L’exemple ci-dessous présente un exemple avancé en ajoutant un reverse proxy (https://traefik.io) et des outils de monitoring pour gérer les points d’entrées de l’application (sécurité, répartition de charges, …).
Commencez par le compose.yml qui est plus simple :
compose.yml
# =========================================
# Compose BASIQUE pour dev JPA/REST
# PostgreSQL + Application Quarkus
# =========================================
services:
# Base de données PostgreSQL
postgres:
# Image officielle PostgreSQL Alpine
image: postgres:16-alpine
# Les variables d'environnement peuvent être définies dans un fichier .env
container_name: postgres-db
environment:
POSTGRES_DB: ${DB_NAME:-products}
POSTGRES_USER: ${DB_USER:-tpuser}
POSTGRES_PASSWORD: ${DB_PASSWORD:-Tp@2026}
ports:
# Exposer sur l'hôte pour accès direct (DBeaver, pgAdmin, etc.)
- "${DB_HOST_PORT:-15432}:5432"
volumes:
# Persistance des données dans un volume nommé
- postgres_data:/var/lib/postgresql/data
networks:
# Connexion au réseau commun
- product-network
# Vérification de l'état de santé de PostgreSQL
healthcheck:
test:
[
"CMD-SHELL",
"pg_isready -U ${DB_USER:-tpuser} -d ${DB_NAME:-products}",
]
interval: 10s
timeout: 5s
retries: 5
start_period: 10s
# Application Quarkus JPA/REST
product-catalog:
# Image de l'application, configurable via des variables d'environnement
image: ${IMAGE_GROUP:-brunoe}/${IMAGE_NAME:-product-catalog}:${IMAGE_TAG:-1.0.0-jib}
# Dépendance sur PostgreSQL avec vérification de santé
depends_on:
postgres:
condition: service_healthy
environment:
# Configuration base de données pour Quarkus
DB_HOST: postgres
DB_PORT: 5432
DB_USER: ${DB_USER:-tpuser}
DB_PASSWORD: ${DB_PASSWORD:-Tp@2026}
# Stratégie Hibernate (update pour dev, validate pour prod)
HIBERNATE_GENERATION: ${HIBERNATE_GENERATION:-update}
# Logs
LOG_LEVEL: ${LOG_LEVEL:-INFO}
LOG_SQL: ${LOG_SQL:-false}
# JVM Options
JAVA_OPTS: >-
-Xms256m
-Xmx512m
-XX:+UseContainerSupport
-XX:MaxRAMPercentage=75.0
ports:
# HTTP direct (pour developpement)
- "${APP_HTTP_PORT:-8080}:8080"
networks:
- product-network
# Vérification de l'état de santé de l'application Quarkus
healthcheck:
test:
["CMD-SHELL", "curl -f http://localhost:8080/health/ready || exit 1"]
interval: 30s
timeout: 5s
retries: 5
start_period: 30s
volumes:
postgres_data:
driver: local
networks:
product-network:
driver: bridgeLISEZ LE README (le début sur les conteneurs) très attentivement pour comprendre la configuration pour découvrir les meilleures pratiques utilisées dans cet exemple :
if [ -f compose.prod.yml ]; then
docker compose --file compose.prod.yml up --detach
else
echo "(skipped: no compose.prod.yml in $(pwd))"
fiif [ -f compose.yml ] || [ -f compose.prod.yml ]; then
docker compose ps
else
echo "(skipped: no compose project in $(pwd))"
fiNAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
notebook-java-rest-sample-quarkus-postgres-1 postgres:16-alpine "docker-entrypoint.s…" postgres 33 seconds ago Up 27 seconds (healthy) 5432/tcp
notebook-java-rest-sample-quarkus-product-catalog-1 brunoe/product-catalog:1.0.0-jib "/opt/jboss/containe…" product-catalog 29 seconds ago Up 3 seconds (health: starting) 8080/tcp, 8443/tcp
notebook-java-rest-sample-quarkus-traefik-1 traefik:v3.0 "/entrypoint.sh --pi…" traefik 33 seconds ago Up 27 seconds (healthy) 0.0.0.0:8080->8080/tcp, [::]:8080->8080/tcp, 0.0.0.0:8888->80/tcp, [::]:8888->80/tcp, 0.0.0.0:5443->443/tcp, [::]:5443->443/tcp
if [ -f compose.prod.yml ]; then
docker compose --file compose.prod.yml down -v
else
echo "(skipped: no compose.prod.yml in $(pwd))"
fiLorsque l’application grandit, un seul serveur devient vite une limite :
saturation CPU / RAM
point unique de panne
impossibilité de gérer la charge variable
On passe alors d’un outil pensé pour le développement local
à des outils conçus pour exploiter plusieurs machines
Un orchestrateur permet de :
Deux approches outils :
| Critère | Docker Swarm | Kubernetes (K8s) |
|---|---|---|
| Philosophie | Extension naturelle de Docker | Plateforme complète d’orchestration |
| Complexité | Simple et rapide à prendre en main | Plus complexe mais extrêmement puissant |
| Unité de déploiement | Service | Pod (groupe de conteneurs) |
| Installation | docker swarm init |
Installation plus lourde en production ou Cloud managé |
| Cas d’usage typique | PME, projets simples | Standard industriel, Cloud natif, Multi-cloud |
| Écosystème | Limité | Très vaste et extensible |