
Vous avez déjà eu ce problème : « Ça marche sur ma machine, mais pas en production » ? Docker résout exactement ce casse-tête. Ce guide central vous apprend ce qu’est Docker, pourquoi il est devenu incontournable, et vous oriente vers les guides spécialisés selon votre niveau.
Que vous soyez développeur, administrateur système ou simplement curieux de la conteneurisation, vous trouverez ici les fondamentaux pour comprendre Docker et les liens vers tous les guides pratiques du site.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Image vs Conteneur : la différence fondamentale et le cycle de vie (created → running → exited)
- Layers et cache : pourquoi Docker est si efficace pour les builds et téléchargements
- Installation : Docker Engine (Linux) vs Docker Desktop (Windows/macOS) vs Colima
- CLI essentielle : run, ps, logs, exec, build, push — les commandes du quotidien
- Volumes : persistance des données avec volumes nommés, bind mounts et tmpfs
- Réseaux : bridge, host, overlay — connecter et isoler vos conteneurs
- Secrets : gérer mots de passe et tokens sans les exposer dans les images
- Daemon : configurer storage drivers, logging et registry mirrors
- Sécurité : rootless, capabilities, seccomp, scan de vulnérabilités
Qu’est-ce que Docker ?
Section intitulée « Qu’est-ce que Docker ? »Une analogie pour comprendre
Section intitulée « Une analogie pour comprendre »Imaginez que vous déménagiez. Deux options s’offrent à vous :
-
Option classique : emballer chaque objet séparément dans des cartons de tailles différentes, noter sur chaque carton ce qu’il contient, espérer que rien ne casse pendant le transport, puis tout déballer et réorganiser à l’arrivée.
-
Option conteneur : utiliser des conteneurs standards où tout est parfaitement rangé, protégé, et transportable. À l’arrivée, vous ouvrez le conteneur et tout est déjà en place.
Docker fonctionne exactement comme la deuxième option, mais pour vos applications.
Le problème concret que Docker résout
Section intitulée « Le problème concret que Docker résout »Avant Docker, déployer une application ressemblait à un parcours du combattant. Prenons un exemple concret :
Scénario classique : vous développez une application Python 3.11 avec Flask et PostgreSQL. Sur votre machine, tout fonctionne parfaitement. Mais quand vous déployez en production :
- Le serveur a Python 3.9 (pas 3.11)
- La version de PostgreSQL est différente
- Il manque une bibliothèque système
- Les chemins de fichiers ne sont pas les mêmes
Résultat ? Le fameux « ça marche chez moi » — cette phrase que tout développeur a entendue (ou prononcée) au moins une fois.
| Sans Docker | Avec Docker |
|---|---|
| L’app fonctionne sur le poste du dev mais échoue en prod | L’app fonctionne de manière identique partout |
| Chaque serveur nécessite une configuration manuelle | L’environnement est packagé avec l’application |
| Conflits de versions entre applications | Chaque conteneur a ses propres dépendances isolées |
| Mise à jour risquée (peut casser d’autres apps) | Conteneurs indépendants les uns des autres |
| Déploiement long et risqué | Déploiement rapide et reproductible |
Définition technique
Section intitulée « Définition technique »Docker est une plateforme open source qui permet de packager une application avec tout ce dont elle a besoin (code, bibliothèques, configuration, variables d’environnement) dans une unité appelée conteneur.
Ce conteneur peut ensuite s’exécuter de manière identique sur n’importe quel serveur où Docker est installé — que ce soit votre laptop, un serveur d’entreprise, ou une instance cloud AWS/GCP/Azure.
Docker vs Machine Virtuelle : quelle différence ?
Section intitulée « Docker vs Machine Virtuelle : quelle différence ? »Si vous connaissez les machines virtuelles (VM), vous vous demandez peut-être : « Pourquoi ne pas simplement utiliser une VM ? »
La réponse tient en un mot : légèreté.
Une machine virtuelle embarque un système d’exploitation complet. C’est comme si vous transportiez une maison entière (fondations, murs, toit, plomberie, électricité) pour chaque application. Chaque VM a son propre noyau Linux/Windows, ses propres drivers, ses propres services système.
Un conteneur Docker, lui, partage le noyau Linux de la machine hôte. Il ne transporte que le strict nécessaire : votre application et ses dépendances directes. C’est comme transporter uniquement les meubles et objets personnels, en utilisant les infrastructures (eau, électricité) déjà présentes.
| Critère | Machine virtuelle | Conteneur Docker |
|---|---|---|
| Démarrage | Minutes (boot complet de l’OS) | Secondes (simple processus) |
| Taille disque | Gigaoctets (OS complet) | Mégaoctets (app seule) |
| Mémoire RAM | Réservée en bloc (ex: 4 Go minimum) | Partagée dynamiquement |
| Isolation | Complète (hyperviseur matériel) | Processus (namespaces Linux) |
| Densité | 10-20 VM par serveur | Centaines de conteneurs |
| Portabilité | Moyenne (format VM propriétaire) | Excellente (standard OCI) |
En pratique : vous pouvez lancer des dizaines de conteneurs sur un laptop ordinaire, là où vous seriez limité à 2-3 VM. Et chaque conteneur démarre en 1-2 secondes au lieu de 30-60 secondes pour une VM.
L’histoire de Docker en bref
Section intitulée « L’histoire de Docker en bref »L’histoire de Docker commence en 2010, lorsque Solomon Hykes, un ingénieur français, travaille sur un projet de virtualisation légère chez dotCloud (une plateforme PaaS). L’idée : simplifier le déploiement d’applications en utilisant les conteneurs Linux — une technologie existante (LXC) mais complexe à utiliser.
| Année | Événement | Impact |
|---|---|---|
| 2010 | Création de dotCloud | Solomon Hykes travaille sur la virtualisation légère |
| 2013 | Docker open source | « Build once, run anywhere » — la révolution commence |
| 2014-15 | Adoption explosive | Google, Microsoft, Amazon intègrent Docker |
| 2015 | Fondation de l’OCI | Standardisation des formats de conteneurs |
| 2017 | containerd → CNCF | Kubernetes adopte containerd comme runtime |
| 2020 | K8s deprecate dockershim | Migration vers containerd/CRI-O |
| 2023 | Docker 23.0 | BuildKit devient le builder par défaut |
| Aujourd’hui | Standard de facto | Des millions d’utilisateurs, écosystème OCI |
Parcours d’apprentissage
Section intitulée « Parcours d’apprentissage »Maintenant que vous comprenez les bases, choisissez votre point de départ selon votre niveau et vos objectifs.
🚀 Je débute avec Docker
Section intitulée « 🚀 Je débute avec Docker »📦 Je veux gérer mes données et mon réseau
Section intitulée « 📦 Je veux gérer mes données et mon réseau »🔒 Je veux sécuriser et optimiser
Section intitulée « 🔒 Je veux sécuriser et optimiser »🏗️ Je veux construire des images
Section intitulée « 🏗️ Je veux construire des images »🚢 Je veux maîtriser les images et CI/CD
Section intitulée « 🚢 Je veux maîtriser les images et CI/CD »🔍 Je veux débugger mes conteneurs
Section intitulée « 🔍 Je veux débugger mes conteneurs »🎯 Je veux orchestrer plusieurs conteneurs
Section intitulée « 🎯 Je veux orchestrer plusieurs conteneurs »Concepts fondamentaux
Section intitulée « Concepts fondamentaux »Avant de plonger dans les guides pratiques, maîtrisez les briques de base de Docker. Ces concepts reviendront constamment — les comprendre maintenant vous fera gagner un temps précieux.
Images Docker
Section intitulée « Images Docker »Une image Docker est comme une recette de cuisine. Elle contient toutes les instructions et ingrédients pour préparer un plat (votre application), mais ce n’est pas le plat lui-même.
Plus techniquement, une image est un package immuable qui contient :
- Le code de votre application
- Les bibliothèques et dépendances nécessaires
- Les fichiers de configuration
- Les variables d’environnement
Une fois créée, une image ne change jamais. C’est cette immutabilité qui garantit la reproductibilité.
Conteneurs
Section intitulée « Conteneurs »Un conteneur est une instance en cours d’exécution d’une image. Si l’image est la recette, le conteneur est le plat préparé et servi.
Contrairement à l’image (immuable), un conteneur a un état qui peut changer : des fichiers peuvent être créés, modifiés, supprimés pendant son exécution. Mais attention : ces modifications disparaissent quand le conteneur est supprimé (sauf si vous utilisez des volumes).
Un conteneur fonctionne dans un environnement isolé grâce à deux mécanismes Linux :
- Les namespaces : isolent ce que le conteneur voit (processus, réseau, utilisateurs…)
- Les cgroups : limitent ce que le conteneur utilise (CPU, mémoire, I/O…)
Les couches (Layers)
Section intitulée « Les couches (Layers) »Chaque instruction du Dockerfile crée une couche dans l’image finale. Ces couches sont empilées les unes sur les autres et forment ensemble l’image complète.
L’intérêt de ce système de couches est l’optimisation :
- Cache : si une couche n’a pas changé, Docker la réutilise au lieu de la reconstruire
- Partage : plusieurs images basées sur la même image de base partagent les couches communes
- Téléchargement : seules les couches manquantes sont téléchargées
Les volumes résolvent un problème fondamental : comment conserver des données alors que les conteneurs sont éphémères ?
| Type | Description | Cas d’usage |
|---|---|---|
| Volume nommé | Géré par Docker, stocké dans /var/lib/docker/volumes/ | Bases de données, fichiers persistants |
| Bind mount | Pointe vers un chemin sur l’hôte | Développement (code source) |
| tmpfs | Stocké en mémoire uniquement | Données sensibles temporaires |
Docker crée automatiquement des réseaux virtuels pour que vos conteneurs puissent communiquer entre eux et avec l’extérieur.
| Type de réseau | Description | Quand l’utiliser |
|---|---|---|
| bridge | Réseau isolé par défaut | Applications multi-conteneurs sur une seule machine |
| host | Partage la pile réseau de l’hôte | Performance réseau maximale (pas d’isolation) |
| overlay | Communication entre hôtes différents | Clusters Docker Swarm ou Kubernetes |
| none | Pas de réseau | Conteneurs sans accès réseau (sécurité) |
→ Guide complet des réseaux Docker
Les 8 guides Docker en détail
Section intitulée « Les 8 guides Docker en détail »Cette section regroupe tous les guides Docker du site. Chacun est autonome mais ils se complètent pour former un parcours complet.
| Guide | Pour qui ? | Temps de lecture |
|---|---|---|
| Concepts | Débutants | 15 min |
| Installation | Débutants | 15 min |
| CLI | Débutants → Intermédiaires | 20 min |
| Volumes | Intermédiaires | 15 min |
| Réseaux | Intermédiaires | 15 min |
| Secrets | Intermédiaires → Avancés | 15 min |
| Daemon | Avancés | 20 min |
| Sécurité | Avancés → Experts | 30 min |
L’écosystème Docker
Section intitulée « L’écosystème Docker »Docker ne se limite pas au moteur de conteneurs. Voici les composants clés de l’écosystème :
Docker Engine
Le cœur : daemon + CLI pour créer et gérer les conteneurs. C’est ce que vous installez sur un serveur Linux.
Docker Hub
Registre public avec des milliers d’images officielles (nginx, postgres, python…). Gratuit pour les images publiques.
Docker Compose
Outil pour définir et lancer des applications multi-conteneurs via un fichier YAML. Indispensable pour le développement.
Docker Desktop
Application GUI pour Windows et macOS. Inclut Engine, CLI, Compose. Attention : licence commerciale pour les entreprises > 250 employés.
Alternatives à connaître
Section intitulée « Alternatives à connaître »Docker n’est pas le seul outil de conteneurisation. Selon votre contexte, ces alternatives peuvent être pertinentes :
| Outil | Description | Quand l’utiliser |
|---|---|---|
| Podman | Compatible Docker, rootless par défaut | Sécurité renforcée, environnements sans daemon |
| Colima | Alternative légère à Docker Desktop | macOS, éviter la licence Docker Desktop |
| containerd | Runtime bas niveau | Kubernetes (qui l’utilise en interne) |
| nerdctl | CLI compatible Docker pour containerd | Utiliser containerd avec la syntaxe Docker |
À retenir
Section intitulée « À retenir »-
Docker résout le problème « ça marche chez moi » en packageant l’application avec tout son environnement dans un conteneur portable.
-
Un conteneur n’est pas une VM : il partage le noyau Linux de l’hôte, démarre en secondes, et consomme beaucoup moins de ressources.
-
Image = recette, Conteneur = plat : l’image est immuable (template), le conteneur est l’instance en cours d’exécution.
-
Le système de layers optimise tout : cache de build, partage entre images, téléchargements partiels.
-
Les volumes persistent les données au-delà de la vie du conteneur — indispensable pour les bases de données.
-
Docker Compose est votre ami pour les applications multi-conteneurs (web + base de données + cache…).
-
La sécurité n’est pas optionnelle : images officielles, scans de vulnérabilités, moindre privilège, rootless si possible.
FAQ — Questions fréquentes
Section intitulée « FAQ — Questions fréquentes »Docker est une plateforme de conteneurisation qui permet d'empaqueter, distribuer et exécuter des applications dans des environnements isolés appelés conteneurs.
Définition
- Conteneur : unité légère et portable qui embarque l'application et toutes ses dépendances
- Image : modèle immuable servant de base aux conteneurs
- Registre : dépôt centralisé d'images (Docker Hub, registres privés)
Avantages clés
- Portabilité : "fonctionne partout" (dev, test, prod)
- Isolation : chaque conteneur a son propre système de fichiers
- Légèreté : partage le noyau de l'hôte (vs machines virtuelles)
- Reproductibilité : même environnement sur tous les systèmes
Architecture
┌─────────────────────────────────┐
│ Applications Docker │
├─────────────────────────────────┤
│ Conteneurs (isolés) │
├─────────────────────────────────┤
│ Docker Engine (démon) │
├─────────────────────────────────┤
│ Système d'exploitation │
└─────────────────────────────────┘
Cas d'usage
- Développement : environnements identiques pour toute l'équipe
- CI/CD : tests automatisés dans des conteneurs jetables
- Microservices : déploiement et mise à l'échelle indépendants
Un moteur de conteneurs (container engine) est le logiciel responsable de la création, du démarrage et de la gestion des conteneurs.
Rôles principaux
| Fonction | Description |
|---|---|
| Build | Créer des images à partir de Dockerfile |
| Run | Démarrer et arrêter les conteneurs |
| Isolation | Namespace, cgroups, capabilities |
| Réseau | Créer des réseaux virtuels entre conteneurs |
| Stockage | Gérer les volumes et bind mounts |
| Sécurité | Appliquer les politiques de sécurité |
Composants Docker Engine
# Vérifier le moteur
docker version
docker info
# Architecture
systemctl status docker # Démon dockerd
docker ps # CLI client
Alternatives à Docker
- Podman : compatible Docker, sans démon (plus sécurisé)
- containerd : runtime bas niveau (utilisé par Kubernetes)
- CRI-O : optimisé pour Kubernetes
Voici un comparatif des principaux moteurs de conteneurs selon leurs particularités :
| Moteur | Type | Particularités | Cas d'usage |
|---|---|---|---|
| Docker | Container engine complet | Écosystème mature, Docker Hub, Compose | Développement, production générale |
| Podman | Compatible Docker, daemonless | Sans démon root, pods, compatible CLI Docker | Sécurité, environnements non-root |
| containerd | Runtime bas niveau | Léger, intégré dans Kubernetes et Docker | Production Kubernetes |
| CRI-O | Runtime Kubernetes | Optimisé pour CRI, images OCI uniquement | Clusters Kubernetes dédiés |
| LXC/Incus | Conteneurs système | Machines virtuelles légères, init complet | Migration VM → conteneurs |
Exemples de commandes
# Docker (avec démon)
sudo docker run -d nginx
# Podman (sans démon)
podman run -d nginx
podman pod create mon-pod # Support natif des pods
# containerd (via ctr)
sudo ctr images pull docker.io/library/nginx:latest
sudo ctr run docker.io/library/nginx:latest nginx-ctr
Comment choisir ?
- Docker : développement, apprentissage, écosystème riche
- Podman : sécurité, CI/CD sans privilèges root
- containerd/CRI-O : clusters Kubernetes en production
Voici les bonnes pratiques essentielles pour une configuration Docker robuste en production :
Configuration système
| Aspect | Configuration | Justification |
|---|---|---|
| Stockage | Partition dédiée /var/lib/docker |
Éviter saturation du système si images/volumes consomment l'espace |
| Logs | Driver json-file avec rotation |
max-size: 10m, max-file: 3 pour limiter la croissance |
| Démon | Fichier /etc/docker/daemon.json |
Centraliser la config (log-driver, storage-driver, etc.) |
Sécurité réseau
{
"icc": false, // Désactiver communication inter-conteneurs par défaut
"userland-proxy": false,
"no-new-privileges": true
}
Limitations de ressources
# Limiter CPU et mémoire
docker run -d \
--memory="512m" \
--memory-swap="1g" \
--cpus="1.5" \
--restart=unless-stopped \
mon-app
Sécurité des conteneurs
# Dans le Dockerfile
USER node # Ne pas exécuter en root
# Images de confiance
FROM node:20-alpine # Images officielles minimales
# Health checks
HEALTHCHECK --interval=30s --timeout=3s \
CMD node healthcheck.js
Monitoring et observabilité
# Métriques Docker
docker stats
# Logs centralisés
# Configurer un driver de logs (syslog, fluentd, splunk)
Gestion des secrets
# Utiliser Docker secrets (Swarm) ou variables d'environnement sécurisées
docker secret create db_password ./password.txt
Checklist production
- ✅ Partition dédiée pour
/var/lib/docker - ✅ Rotation des logs configurée
- ✅ Utilisateurs non-root dans les conteneurs
- ✅ Ressources limitées (CPU/RAM)
- ✅ Images officielles et régulièrement mises à jour
- ✅ Health checks sur tous les services
- ✅ Monitoring actif (Prometheus, Grafana)
- ✅ Backups automatisés des volumes
La sécurisation Docker repose sur le principe du moindre privilège et des couches de défense en profondeur.
Principe du moindre privilège
# Limiter les capabilities Linux
docker run --cap-drop=ALL --cap-add=NET_BIND_SERVICE mon-app
# Exécuter en utilisateur non-root
docker run --user 1000:1000 mon-app
# Conteneur en lecture seule
docker run --read-only --tmpfs /tmp mon-app
# Désactiver les nouveaux privilèges
docker run --security-opt=no-new-privileges mon-app
Modules de sécurité (LSM)
# AppArmor (Ubuntu/Debian)
docker run --security-opt apparmor=docker-default nginx
# SELinux (RHEL/CentOS)
docker run --security-opt label=type:svirt_apache_t nginx
Confiance des images
# Activer Docker Content Trust (signatures)
export DOCKER_CONTENT_TRUST=1
docker pull nginx # Vérifie la signature
# Scanner les vulnérabilités avec Trivy
docker run aquasec/trivy image nginx:latest
Sécurité réseau
# Filtrage réseau (réseau personnalisé)
docker network create --internal backend
# Pas d'exposition inutile de ports
# ❌ docker run -p 0.0.0.0:3306:3306 mysql
# ✅ docker run -p 127.0.0.1:3306:3306 mysql
Gestion des secrets
# Docker Swarm secrets
echo "mon_mot_de_passe" | docker secret create db_password -
docker service create --secret db_password mon-api
# Variables d'environnement (fichier séparé)
docker run --env-file .env.production mon-app
Audit et monitoring
# Audit des événements Docker
auditctl -w /var/lib/docker -k docker
auditctl -w /usr/bin/docker -k docker
# Logs centralisés
# Configurer syslog/fluentd dans /etc/docker/daemon.json
Images minimales
# Préférer Alpine ou scratch
FROM alpine:latest # ~5 MB vs debian:latest ~120 MB
# Multi-stage pour exécutables statiques
FROM scratch
COPY --from=builder /app/binary /
ENTRYPOINT ["/binary"]
Checklist sécurité
- ✅ Utilisateur non-root dans tous les conteneurs
- ✅ Capabilities minimales (--cap-drop=ALL)
- ✅ AppArmor/SELinux activés
- ✅ Content Trust activé (DOCKER_CONTENT_TRUST=1)
- ✅ Scan régulier des images (Trivy, Clair)
- ✅ Réseau interne pour services backend
- ✅ Secrets gérés via Docker secrets ou vault
- ✅ Audit actif sur /var/lib/docker
- ✅ Images minimales (Alpine/scratch)
- ✅ Mises à jour régulières des images de base
Docker propose trois types de stockage pour persister les données au-delà de la vie d'un conteneur.
Comparaison des types
| Type | Emplacement | Gestion | Cas d'usage |
|---|---|---|---|
| Volumes | /var/lib/docker/volumes/ |
Docker (recommandé) | Bases de données, données applicatives |
| Bind mounts | Chemin absolu sur l'hôte | Utilisateur | Développement, fichiers de configuration |
| tmpfs | Mémoire RAM uniquement | Éphémère | Secrets, données temporaires sensibles |
Commandes volumes
# Créer un volume
docker volume create mon-volume
# Lister les volumes
docker volume ls
# Inspecter un volume
docker volume inspect mon-volume
# Utiliser un volume
docker run -v mon-volume:/data postgres
# Supprimer un volume
docker volume rm mon-volume
Exemples Docker Compose
services:
db:
image: postgres
volumes:
- db-data:/var/lib/postgresql/data # Volume nommé
- ./init.sql:/docker-entrypoint-initdb.d/init.sql:ro # Bind mount
volumes:
db-data: # Déclaration du volume
Backup et restore
# Sauvegarder un volume
docker run --rm -v mon-volume:/data -v $(pwd):/backup alpine tar czf /backup/data.tar.gz /data
# Restaurer un volume
docker run --rm -v mon-volume:/data -v $(pwd):/backup alpine tar xzf /backup/data.tar.gz -C /
Plugins de stockage
- Local : stockage par défaut sur l'hôte
- NFS : partage réseau entre plusieurs hôtes
- SSHFS : montage distant via SSH
- Cloud : Azure Files, AWS EFS, Google Filestore
Une image Docker est un modèle immuable qui contient tout le nécessaire pour exécuter une application, tandis qu'un conteneur est une instance en cours d'exécution de cette image.
Comparaison
| Aspect | Image | Conteneur |
|---|---|---|
| Nature | Modèle statique, immuable | Instance dynamique, éphémère |
| Stockage | Système de fichiers en couches (layers) | Couche en lecture/écriture au-dessus de l'image |
| État | Aucun état (stateless) | Possède un état (stateful) |
| Partage | Peut servir de base à plusieurs conteneurs | Isolé, ne peut pas être partagé |
| Cycle de vie | Créée une fois, utilisée plusieurs fois | Créé, démarré, arrêté, supprimé |
Analogie
Image = classe en programmation → Conteneur = objet (instance de la classe)
Commandes
# Lister les images
docker images
# Lister les conteneurs en cours d'exécution
docker ps
# Lister tous les conteneurs (actifs et arrêtés)
docker ps -a
# Créer un conteneur à partir d'une image
docker run nginx # Image nginx → Conteneur nginx
Structure en couches
Chaque image est composée de layers (couches) en lecture seule. Le conteneur ajoute une couche en lecture/écriture au-dessus.
Docker propose plusieurs modes réseau pour connecter les conteneurs entre eux ou au monde extérieur.
Modes réseau
| Mode | Description | Cas d'usage |
|---|---|---|
| bridge | Réseau virtuel isolé (par défaut) | Communication entre conteneurs sur un même hôte |
| host | Partage la pile réseau de l'hôte | Performance maximale (pas de NAT) |
| overlay | Réseau multi-hôtes (Swarm/Kubernetes) | Clusters de conteneurs sur plusieurs machines |
| macvlan | Attribution d'adresses MAC virtuelles | Intégration au réseau physique existant |
| none | Aucun réseau | Isolation réseau complète |
Exemple : Réseau bridge personnalisé
# Créer un réseau bridge
docker network create mon-reseau
# Lancer des conteneurs dans ce réseau
docker run -d --name db --network mon-reseau postgres
docker run -d --name api --network mon-reseau -p 3000:3000 mon-api
# Les conteneurs peuvent communiquer par leur nom
# Depuis 'api' : psql -h db -U postgres
Exposition de ports
# Mapper un port hôte → conteneur
docker run -p 8080:80 nginx # localhost:8080 → nginx:80
# Publier tous les ports EXPOSE du Dockerfile
docker run -P nginx
DNS interne
Docker fournit un DNS intégré : les conteneurs se résolvent mutuellement par leur nom sur les réseaux personnalisés (bridge/overlay).
Docker Compose permet de définir et gérer des applications multi-conteneurs à l'aide d'un seul fichier YAML déclaratif.
Avantages
- Simplicité : un fichier
docker-compose.ymlremplace plusieursdocker run - Reproductibilité : toute l'équipe utilise la même stack
- Gestion du cycle de vie : démarrage/arrêt/rebuild de tous les services en une commande
- Environnements multiples : profils dev/test/prod dans le même fichier
Exemple complet
services:
db:
image: postgres:15-alpine
environment:
POSTGRES_PASSWORD_FILE: /run/secrets/db_password
volumes:
- db-data:/var/lib/postgresql/data
networks:
- backend
secrets:
- db_password
healthcheck:
test: ["CMD", "pg_isready", "-U", "postgres"]
interval: 10s
api:
build: ./api
env_file: .env
depends_on:
db:
condition: service_healthy
networks:
- backend
- frontend
web:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
networks:
- frontend
profiles:
- prod
networks:
backend:
frontend:
volumes:
db-data:
secrets:
db_password:
file: ./db_password.txt
Commandes essentielles
# Démarrer tous les services
docker compose up -d
# Voir les logs en temps réel
docker compose logs -f api
# Lister les conteneurs
docker compose ps
# Exécuter une commande dans un service
docker compose exec api sh
# Arrêter et supprimer
docker compose down
# Activer un profil spécifique
docker compose --profile prod up -d
Variables d'environnement
# Fichier .env
API_PORT=3000
DB_VERSION=15
# Référencées dans docker-compose.yml
ports:
- "${API_PORT}:3000"
Docker et Kubernetes sont complémentaires : Docker conteneurise les applications, Kubernetes les orchestre à grande échelle.
Comparaison
| Aspect | Docker | Kubernetes |
|---|---|---|
| Niveau | Conteneur individuel | Cluster de conteneurs |
| Scope | Machine unique | Multi-machines (cluster) |
| Objectif | Empaqueter et exécuter | Orchestrer et automatiser |
| Scaling | Manuel (docker run x N) |
Automatique (HorizontalPodAutoscaler) |
| Haute disponibilité | Non (conteneur unique) | Oui (réplication, self-healing) |
| Configuration | CLI/docker-compose.yml | Manifestes YAML (Deployment, Service, etc.) |
| Complexité | Simple, facile à apprendre | Courbe d'apprentissage élevée |
Exemples
Docker : exécution simple
# Lancer 3 répliques manuellement
docker run -d --name web1 -p 8001:80 nginx
docker run -d --name web2 -p 8002:80 nginx
docker run -d --name web3 -p 8003:80 nginx
# Pas de load balancing automatique
# Pas de redémarrage automatique si crash
Kubernetes : orchestration automatique
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3 # 3 répliques automatiques
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
type: LoadBalancer
selector:
app: nginx
ports:
- port: 80
targetPort: 80
# Kubernetes gère automatiquement :
kubectl apply -f deployment.yaml
# → 3 pods répartis sur le cluster
# → Load balancing automatique
# → Redémarrage auto si crash (self-healing)
# → Rolling updates sans downtime
Fonctionnalités Kubernetes
- Auto-scaling : ajustement automatique du nombre de pods selon la charge (CPU/RAM)
- Self-healing : redémarrage automatique des pods en échec
- Rolling updates : déploiements sans interruption (A/B testing, canary)
- Service discovery : DNS interne pour communication entre services
- ConfigMaps & Secrets : gestion centralisée de la configuration
- Persistent Volumes : stockage persistant indépendant du cycle de vie des pods
Architecture
Docker :
┌─────────────────┐
│ Machine │
│ ┌───┬───┬───┐ │
│ │C1 │C2 │C3 │ │ (Conteneurs isolés)
│ └───┴───┴───┘ │
│ Docker Engine │
└─────────────────┘
Kubernetes :
┌────────────────────────────────────┐
│ Cluster K8s │
│ ┌─────────┐ ┌─────────┐ │
│ │ Node 1 │ │ Node 2 │ ... │
│ │ ┌─┬─┬─┐ │ │ ┌─┬─┐ │ │
│ │ │P│P│P│ │ │ │P│P│ │ │ (Pods répartis)
│ │ └─┴─┴─┘ │ │ └─┴─┘ │ │
│ └─────────┘ └─────────┘ │
│ Control Plane (API, Scheduler) │
└────────────────────────────────────┘
Quand utiliser quoi ?
| Contexte | Outil recommandé |
|---|---|
| Développement local | Docker + Docker Compose |
| Application simple (1-5 conteneurs) | Docker |
| Production à grande échelle (>10 conteneurs) | Kubernetes |
| Besoin de haute disponibilité | Kubernetes |
| Multi-cloud ou cloud hybride | Kubernetes |
| Équipe sans expertise DevOps | Docker (plus simple) |
Un Dockerfile est un fichier texte contenant les instructions pour construire une image Docker de manière reproductible.
Instructions principales
| Instruction | Rôle | Exemple |
|---|---|---|
| FROM | Image de base | FROM node:20-alpine |
| WORKDIR | Répertoire de travail | WORKDIR /app |
| COPY | Copier des fichiers | COPY package*.json ./ |
| RUN | Exécuter des commandes | RUN npm install |
| EXPOSE | Documenter les ports | EXPOSE 3000 |
| ENV | Variables d'environnement | ENV NODE_ENV=production |
| CMD | Commande par défaut | CMD ["npm", "start"] |
| ENTRYPOINT | Point d'entrée fixe | ENTRYPOINT ["docker-entrypoint.sh"] |
Exemple multi-stage (optimisation)
# Étape 1 : Build
FROM node:20 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Étape 2 : Production
FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY package*.json ./
RUN npm ci --only=production
EXPOSE 3000
CMD ["node", "dist/index.js"]
Utilisation
# Construire une image
docker build -t mon-app:1.0 .
# Lancer un conteneur
docker run -p 3000:3000 mon-app:1.0
Bonnes pratiques
- Utiliser des images de base officielles et légères (Alpine)
- Créer un fichier .dockerignore (node_modules, .git)
- Minimiser les couches : regrouper les RUN
- Multi-stage builds : images finales plus petites
- Ne pas exécuter en root :
USER node