Compose Avancé
Sécuriser les démarrages et l'environnement
Le lancement des conteneurs pose un problème fondamental : Un service démarré ne signifie pas qu'il est prêt à l'usage. Par exemple, au démarrage, PostgreSQL prend 5 à 10 secondes pour allouer sa RAM et monter ses fichiers. Si votre API tente de s'y connecter immédiatement (à la milliseconde 1), elle plantera violemment (`Connexion Refusée`).
Le Problème du "Depends_on" classique
Historiquement on utilisait `depends_on: [db]`. Mais cela attend simplement que le processus Docker de la DB *démarre*. Pas qu'elle soit *Healthy* (qu'elle écoute vraiment les requêtes). La solution ultime est le Healthcheck.
services:
api:
image: mon-api
depends_on:
db:
condition: service_healthy # ⏳ L'API restera "Paused" tant que ce n'est pas Healthy
db:
image: postgres:15
healthcheck: # 🩺 La sonde de Prod
test: ["CMD-SHELL", "pg_isready -U superadmin"] # Ping interne natif PostgreSQL
interval: 5s # Vérifie toutes les 5 secondes
timeout: 3s # Si ça prend plus de 3s, c'est mort
retries: 5 # Au bout de 5 morts, le conteneur passe de "Starting" à "Unhealthy"
Désintégrer le .env (Variables d'Environnement)
Ne mettez JAMAIS de mots de passe ou clés d'API dans votre fichier docker-compose.yml. Si ce fichier finit sur GitHub (et il y finira, tôt ou tard !), toutes vos clés d'API et mots de passe seront exposés publiquement en clair. Utilisez l'injection par fichier env_file et le fichier .env, qui lui ne sera jamais commité.
Checklist : Sécuriser les secrets
Cochez chaque étape validée avant de pousser votre projet sur Git :
DB_PASSWORD=SuperSecretPassWord123!
JWT_SECRET=x8Lkj29#
services:
db:
image: postgres:15
env_file: # Docker injecte tout le fichier .env en un coup !
- .env
api:
image: mon-api
environment:
- DATABASE_PASSWORD=${DB_PASSWORD} # Injection sélective. La syntaxe ${VAR} appelle l'hôte !
Les Profils (Séparer le Dev de la Prod)
Vous souhaitez un conteneur d'administration visuelle (comme Adminer ou PgAdmin) pour vous aider en dev local. Mais si vous lancez en production, vous ne voulez surtout pas inclure ce service potentiellement vulnérable ! C'est le rôle des Profils.
services:
api:
image: mon-api
# (Démarre toujours par défaut)
adminer:
image: adminer
profiles:
- debug # 🛡️ Ne démarrera JAMAIS sauf ordre contraire !
ports:
- "8080:8080"
docker compose up -d (L'Adminer est ignoré).En developpement :
docker compose --profile debug up -d (L'API et l'Adminer démarrent).
Bonus : Composer plusieurs fichiers (Override)
Puisque Compose lit plusieurs fichiers dans l'ordre, une astuce Pro consiste à définir une configuration de base partagée (docker-compose.yml), et à la surcharger avec un second fichier spécifique à l'environnement. Pas de copier-coller, pas de risque d'oublier de synchroniser les deux !
docker-compose.yml (base commune)services:
api:
build: .
environment:
- NODE_ENV=production
docker-compose.dev.yml (surcharge Dev)services:
api:
volumes:
- ./src:/app/src # Hot-reload local
environment:
- NODE_ENV=development
# Dev : Fusionne les deux, le .dev.yml écrase les clés communes
docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d
# Prod : On utilise uniquement le fichier de base (pas de volume dev exposé !)
docker compose up -d