Docker
Les applications modernes s'appuient sur une combinaison de services — base de données, cache, broker de messages, runtime applicatif — chacun avec ses dépendances de version spécifiques. Sans conteneurs, chaque développeur configure son environnement local manuellement, les versions divergent entre machines, et le déploiement implique de reconfigurer chaque serveur à la main. Docker résout ces problèmes en encapsulant l'application et ses dépendances dans une unité portable et reproductible.
Le problème sans conteneurs
Développement
Dans une équipe sans conteneurs, chaque développeur installe directement les services sur son OS — PostgreSQL, Redis, Node.js, Python. Le processus varie selon l'OS (apt, brew, installeur Windows), les versions diffèrent d'une machine à l'autre, et la moindre mise à jour peut casser la configuration locale d'un autre développeur. Le problème classique : "ça fonctionne sur ma machine" mais pas en CI, ni en production.
Déploiement
Le déploiement traditionnel repose sur un guide textuel transmis à l'équipe ops : installer les dépendances, configurer les variables d'environnement, démarrer les services dans le bon ordre. Chaque étape est manuelle, chaque serveur est configuré à la main, et toute divergence entre la documentation et la réalité se traduit par une panne en production.
Dev → artifact (jar, wheel, binaire)
+ instructions textuelles
→ Ops configure le serveur
→ déploiement (erreurs fréquentes)
La solution Docker
Docker encapsule l'application et son environnement d'exécution dans une image. L'image contient le code, les dépendances système, les variables de configuration par défaut — tout ce qu'il faut pour faire tourner le service. L'image est construite une fois, testée en CI, et déployée identiquement sur chaque environnement.
Dev → Dockerfile → image Docker
→ CI : tests
→ Registry : stockage
→ Prod : docker run
La seule dépendance sur le serveur de production est le daemon Docker — une installation unique, indépendante de l'application déployée.
Image et conteneur
Une image est un artefact statique — un snapshot du filesystem de l'application à un instant donné, versionné et stocké dans un registry.
Un conteneur est une instance en cours d'exécution d'une image. On peut démarrer plusieurs conteneurs à partir de la même image, chacun dans son propre namespace réseau et filesystem.
# Télécharger une image
docker pull postgres:16-alpine
# Démarrer un conteneur depuis cette image
docker run -d \
--name postgres \
-e POSTGRES_PASSWORD=secret \
-p 5432:5432 \
postgres:16-alpine
# Lister les conteneurs en cours
docker ps
Structure d'une image en couches
Une image Docker est constituée de couches superposées, chacune correspondant à une instruction du Dockerfile. Les couches sont immuables et partagées entre images — si deux images utilisent la même base Alpine, la couche Alpine n'est stockée qu'une fois sur le disque.
FROM python:3.12-alpine # couche 1 : image de base
RUN pip install fastapi uvicorn # couche 2 : dépendances
COPY . /app # couche 3 : code source
CMD ["uvicorn", "main:app"] # couche 4 : commande de démarrage
Quand l'image est reconstruite, seules les couches modifiées et celles qui les suivent sont recalculées. Si le code source change mais pas les dépendances, la couche 2 est réutilisée depuis le cache — le build est rapide.
Docker Compose
Pour une application multi-services, docker-compose.yml décrit l'ensemble de la stack et les relations entre services :
services:
api:
build: ./api
ports:
- "8000:8000"
environment:
DATABASE_URL: postgresql://postgres:secret@db:5432/myapp
depends_on:
- db
db:
image: postgres:16-alpine
environment:
POSTGRES_PASSWORD: secret
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:
docker compose up -d # démarrer la stack en arrière-plan
docker compose logs -f # suivre les logs
docker compose down # arrêter et supprimer les conteneurs
depends_on garantit que db démarre avant api. Le nom du service (db) sert de hostname dans le réseau Docker Compose — api peut joindre la base de données via db:5432 sans connaître l'IP du conteneur.