flowchart LR
A[🐍 API Python<br>FastAPI/Flask] --> B[🗄️ Base de données<br>PostgreSQL]
A --> C[📊 Dashboard<br>Streamlit]
A --> D[💾 Cache<br>Redis]
C --> A
0.0.1 🎯 Objectifs d’apprentissage
À l’issue de ce module, tu seras capable de :
- Expliquer pourquoi on a besoin d’orchestrer plusieurs conteneurs
- Écrire un fichier docker-compose.yml complet
- Configurer services, réseaux et volumes dans Compose
- Déployer une application multi-conteneurs (API + BDD)
- Maîtriser les commandes Compose du quotidien
📚 Prérequis : Module Technique 1 — Docker installé et bases maîtrisées
⏱️ Temps estimé : 3 heures
1 Pourquoi Docker Compose ?
1.1 Le problème des applications multi-services
En pratique, une application Data Science ne tourne jamais seule. Elle a besoin de services complémentaires :
Sans Compose, il faudrait lancer manuellement chaque conteneur avec de longues commandes docker run. Compose permet de tout définir dans un seul fichier YAML.
1.2 Structure du fichier docker-compose.yml
# docker-compose.yml
version: "3.8"
services:
api:
build: ./api
ports:
- "8000:8000"
environment:
- DATABASE_URL=postgresql://user:pass@db:5432/assurance
depends_on:
- db
db:
image: postgres:15
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
POSTGRES_DB: assurance
volumes:
- pg_data:/var/lib/postgresql/data
ports:
- "5432:5432"
volumes:
pg_data:💡 Point clé
Dans Compose, les services communiquent entre eux par leur nom de service. Ici, l’API accède à la BDD via db:5432 — pas besoin d’adresse IP. Compose crée automatiquement un réseau interne.
2 Les concepts clés de Compose
2.1 Services
Un service = un conteneur (ou plusieurs réplicas) défini par une image ou un build context.
| Propriété | Description |
|---|---|
image |
Image Docker à utiliser |
build |
Chemin vers un Dockerfile |
ports |
Mapping de ports host:conteneur |
environment |
Variables d’environnement |
depends_on |
Ordre de démarrage |
volumes |
Montages de données |
restart |
Politique de redémarrage |
2.2 Volumes
Les volumes persistent les données au-delà du cycle de vie des conteneurs :
volumes:
pg_data: # Volume nommé (géré par Docker)
services:
db:
volumes:
- pg_data:/var/lib/postgresql/data # Volume nommé
- ./init.sql:/docker-entrypoint-initdb.d/init.sql # Bind mount2.3 Réseaux
Par défaut, Compose crée un réseau pour chaque projet. Tu peux aussi définir des réseaux personnalisés pour isoler certains services.
3 Application pratique : API + PostgreSQL
3.1 Structure du projet
projet-assurance/
├── docker-compose.yml
├── api/
│ ├── Dockerfile
│ ├── requirements.txt
│ └── main.py
└── db/
└── init.sql
3.2 Le Dockerfile de l’API
FROM python:3.10-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY main.py .
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]3.3 Le script API (main.py)
from fastapi import FastAPI
import psycopg2
import os
app = FastAPI(title="API Assurance")
@app.get("/contrats")
def get_contrats():
conn = psycopg2.connect(os.environ["DATABASE_URL"])
cur = conn.cursor()
cur.execute("SELECT * FROM contrats LIMIT 10")
rows = cur.fetchall()
conn.close()
return {"contrats": rows}4 Les commandes essentielles
| Commande | Description |
|---|---|
docker compose up |
Démarrer tous les services |
docker compose up -d |
Démarrer en arrière-plan |
docker compose down |
Arrêter et supprimer les conteneurs |
docker compose logs -f |
Suivre les logs en temps réel |
docker compose ps |
Lister les services en cours |
docker compose exec api bash |
Entrer dans un service |
docker compose build |
Reconstruire les images |
# Lancer l’application
\(</span> docker compose up -d<br>
<span class="output">[+] Running 3/3</span><br>
<span class="output"> ✔ Network projet_default Created</span><br>
<span class="output"> ✔ Container projet-db-1 Started</span><br>
<span class="output"> ✔ Container projet-api-1 Started</span><br><br>
<span class="comment"># Vérifier que tout tourne</span><br>
<span class="prompt">\) docker compose ps
NAME SERVICE STATUS PORTS
projet-api-1 api running 0.0.0.0:8000->8000/tcp
projet-db-1 db running 0.0.0.0:5432->5432/tcp
5 Bonnes pratiques
5.0.0.1 ❌ À éviter
- Mettre les mots de passe en dur dans le YAML
- Ne pas utiliser
depends_on - Oublier les volumes pour les données persistantes
- Utiliser
latestcomme tag d’image
5.0.0.2 ✅ Recommandé
- Utiliser un fichier
.envpour les secrets - Définir l’ordre de démarrage
- Toujours persister les données de BDD
- Fixer les versions d’images
⚠️ Important
depends_on ne garantit pas que le service est prêt, seulement qu’il est démarré. Pour PostgreSQL, utilise un healthcheck ou un script d’attente dans ton API.
Synthèse
5.0.1 🎯 Les 5 points essentiels
- Compose orchestre plusieurs conteneurs — Un fichier YAML pour toute l’architecture
- Les services communiquent par nom — Pas besoin d’IP, Compose gère le réseau
- Les volumes persistent les données — Indispensable pour les bases de données
depends_ongère l’ordre — Mais pas la disponibilité réelle du service- Le fichier .env protège les secrets — Ne jamais commiter les mots de passe
Auto-évaluation
docker run et docker compose up ?
Réponse : docker run lance un seul conteneur à partir d’une image. docker compose up lance tous les services définis dans le fichier docker-compose.yml, avec leurs réseaux, volumes et dépendances configurés.
Réponse : Par le nom du service défini dans le YAML. Compose crée automatiquement un réseau interne et un DNS. Exemple : l’API accède à PostgreSQL via db:5432 (où db est le nom du service).
Réponse : Un volume nommé est géré par Docker, offrant de meilleures performances et une portabilité accrue. Un bind mount lie un dossier de l’hôte au conteneur — utile en développement, mais moins portable. Pour les données de production (BDD), un volume nommé est préférable.
depends_on garantit-il que PostgreSQL est prêt à recevoir des connexions ?
Réponse : Non. depends_on garantit uniquement que le conteneur est démarré, pas que le service à l’intérieur est opérationnel. PostgreSQL peut prendre quelques secondes pour s’initialiser. Il faut ajouter un healthcheck ou un mécanisme de retry dans l’application.