Chapitre 630 min1 exercice
Docker Compose
Fini les longues commandes docker run. Un fichier compose.yaml décrit tous les conteneurs d'un projet, et une commande les lance.
Pourquoi Compose
Au chapitre précédent, il a fallu créer un réseau, puis lancer deux conteneurs avec la bonne combinaison d'options. Sur un vrai projet, c'est cinq conteneurs. Personne ne retient ça.
Avec Compose, tout est écrit dans compose.yaml, versionné avec le code. Un nouvel arrivant clone le dépôt, tape docker compose up -d, et c'est parti.
Anatomie d'un compose.yaml
Voici exactement l'exercice réseau du chapitre 5, réécrit.
services:
db:
image: postgres:18
environment:
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- db-data:/var/lib/postgresql
adminer:
image: adminer
ports:
- "8081:8080"
depends_on:
- db
volumes:
db-data:| Clé | Équivalent docker run |
|---|---|
services.db | Un conteneur. Le nom db devient aussi son adresse réseau. |
image | L'image à utiliser. Ou build: pour construire depuis un Dockerfile. |
environment | -e |
ports | -p |
volumes | -v |
depends_on | Démarre db avant adminer. |
volumes (en bas) | Déclare les volumes nommés utilisés plus haut. |
Les commandes du quotidien
À lancer dans le dossier qui contient compose.yaml.
docker compose up -d # crée et démarre tout en arrière-plan
docker compose ps # état des services
docker compose logs -f db # logs d'un service
docker compose exec db sh # shell dans un service qui tourne
docker compose run --rm db psql --version # conteneur jetable, pour une commande
docker compose restart adminer
docker compose up -d --build # reconstruit les images modifiées
docker compose down # arrête et supprime les conteneurs (volumes gardés)
docker compose down -v # idem, et supprime les volumes (données perdues)Variables d'environnement
Écrire un mot de passe en dur dans compose.yaml est une mauvaise habitude. Compose lit automatiquement un fichier .env placé à côté et remplace les ${...}.
DB_PASSWORD=secretLe fichier .env ne se commit pas. Commite plutôt un .env.example avec des valeurs factices, que chacun copie.
cp .env.example .envAttendre qu'un service soit prêt
depends_on seul attend que le conteneur démarre, pas que PostgreSQL accepte les connexions. Ajoute un healthcheck et une condition.
services:
db:
image: postgres:18
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 3s
retries: 10
adminer:
image: adminer
depends_on:
db:
condition: service_healthyTa première stack Compose
- Dans un dossier
stack-demo, écris uncompose.yamlavec PostgreSQL 18 (volume et healthcheck) et Adminer sur le port 8081. - Mets le mot de passe dans un
.env. - Démarre, vérifie l'état avec
docker compose ps, crée une table. - Fais
downpuisup: la table existe-t-elle encore ? Et aprèsdown -v?
Ce que tu dois obtenir
docker compose ps affiche db en état healthy et Adminer répond sur localhost:8081. Après down puis up, ta table est toujours là. Après down -v, elle a disparu.
Un indice
Pars du fichier de la section Anatomie, ajoute le healthcheck, et n'oublie pas le .env. Pour créer la table : docker compose exec db psql -U postgres -c "CREATE TABLE test (id int);"
Voir la solution
services:
db:
image: postgres:18
environment:
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- db-data:/var/lib/postgresql
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 3s
retries: 10
adminer:
image: adminer
ports:
- "8081:8080"
depends_on:
db:
condition: service_healthy
volumes:
db-data:echo "DB_PASSWORD=secret" > .env
docker compose up -d
docker compose ps
docker compose exec db psql -U postgres -c "CREATE TABLE test (id int);"
docker compose down && docker compose up -d
docker compose exec db psql -U postgres -c "\dt"
docker compose down -v