Aller au contenu principal

Docker

· 3 minutes de lecture

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.