
Docker est la plateforme de référence de conteneurisation : elle te permet de packager une application et ses dépendances dans une image (un artefact immuable), puis de l'exécuter partout à l'identique sous forme de conteneur (un processus isolé et léger qui démarre en quelques secondes). La conteneurisation règle le fameux « ça marche sur ma machine » : le conteneur embarque tout ce qu'il faut pour tourner, du code aux bibliothèques système. Objectif de cette page : te faire gagner du temps en t'envoyant immédiatement vers le bon guide, puis te proposer un parcours et une référence rapide.
Choisir ton objectif
Section intitulée « Choisir ton objectif »Parcours recommandé
Section intitulée « Parcours recommandé »Parcours A, De zéro à autonome (débutant)
Section intitulée « Parcours A, De zéro à autonome (débutant) »Ce parcours mène un débutant complet à l'autonomie sur Docker en quatre temps : comprendre les concepts, installer proprement, piloter en ligne de commande, puis persister les données et connecter les conteneurs.
-
Commence par les concepts (image/containeur/layers/volumes/réseaux).
-
Installe Docker proprement selon ton OS.
-
Maîtrise la CLI minimale (run, ps, logs, exec, pull/push).
-
Ajoute la persistance (volumes) puis le réseau (publish ports, DNS).
Parcours B, "Je veux de la prod propre" (intermédiaire)
Section intitulée « Parcours B, "Je veux de la prod propre" (intermédiaire) »Ce parcours vise une mise en production saine : diagnostiquer les incidents, durcir la sécurité au moindre privilège, industrialiser le démon, puis placer les secrets hors des images et du dépôt Git.
-
Ajoute le dépannage (inspect, logs, exit codes, healthchecks).
-
Monte le niveau sécurité (rootless, moindre privilège).
-
Passe en mode opérations (daemon.json, logs, stockage, mirrors).
-
Mets les secrets au bon endroit (pas dans les images, pas dans le Git).
Référence rapide
Section intitulée « Référence rapide »Tu veux une page "réponse immédiate" ? Cette section est faite pour ça.
Concepts (image/containeur/layers), ce qu'il faut retenir
- Image : artefact immuable (comme un binaire buildé ou un paquet).
- Conteneur : process isolé (comme un service systemd) + FS éphémère.
- Layer : diff (comme un commit Git) empilé et cacheable.
- Volume : stockage persistant (comme un PVC local, mais côté Docker).
- Réseau bridge : réseau NAT isolé (comme une VRF "par défaut" Docker).
CLI, les commandes qui comptent vraiment
- "Je lance" :
docker run … - "Je vois" :
docker ps,docker images - "Je comprends" :
docker logs,docker inspect - "J'entre" :
docker exec -it … sh - "Je nettoie" :
docker rm,docker rmi,docker system prune
Volumes, choix rapide
- Bind mount : dev / code local / debug rapide.
- Volume nommé : prod / données applicatives / DB.
- tmpfs : secret temporaire / perf / rien sur disque.
Réseaux, choix rapide
- bridge : cas standard (app multi-conteneurs sur 1 hôte).
- host : perf max, isolation réseau minimale.
- overlay : multi-hôtes (Swarm) / réseau distribué.
Dépannage, "je fais quoi quand ça marche pas"
- Si ça crash : exit code + logs +
inspect(ordre fixe). - Si ça ne répond pas : ports publish + IP/route + DNS + healthcheck.
- Si ça ne pull pas : auth registry + DNS + proxy + certs.
Sécurité, règles simples
- Évite
root(rootless si possible). - Retire les capabilities inutiles, read-only FS si possible.
- Scan d'images, mises à jour régulières.
- Secrets hors image + hors variables exposées.
Les 11 guides Docker (liste officielle du hub)
Section intitulée « Les 11 guides Docker (liste officielle du hub) »Cette table sert de sommaire complet : elle recense tous les guides Docker du site, du plus accessible au plus pointu. La colonne Niveau indique le bagage attendu, pas la difficulté du sujet. Un guide marqué Avancé reste lisible si vous avez suivi les précédents dans l'ordre.
| Guide | Objectif | Niveau |
|---|---|---|
| Concepts | Comprendre l'essentiel | Débutant |
| Installation | Avoir un environnement stable | Débutant |
| CLI | Maîtriser les commandes | Débutant → Intermédiaire |
| Dépannage | Diagnostiquer les problèmes | Intermédiaire |
| Sous le capot | Comprendre l'isolation | Intermédiaire |
| Volumes | Persister les données | Intermédiaire |
| Réseaux | Connecter/exposer | Intermédiaire |
| Secrets | Protéger les credentials | Intermédiaire → Avancé |
| Daemon | Industrialiser l'hôte | Avancé |
| Sécurité | Durcir l'exécution | Avancé → Expert |
| Socket-proxy | Filtrer l'accès à l'API Docker | Avancé → Expert |
Repères : standards et écosystème
Section intitulée « Repères : standards et écosystème »FAQ, Questions fréquentes
Section intitulée « FAQ, Questions fréquentes »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
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
| 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, compatibla 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
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
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
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
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é |
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.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).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"
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 automatiqueapiVersion: 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) |
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
docker run, qui télécharge l'image si besoin puis démarre le conteneur. Pour un premier test :docker run hello-world
Pour lancer un serveur web Nginx en arrière-plan et le publier sur le port 8080 :docker run -d -p 8080:80 nginx
L'option -d détache le conteneur (mode arrière-plan) et -p 8080:80 mappe le port. Vérifiez avec docker ps que le conteneur tourne. Le détail des options est dans le guide de la CLI Docker.Le cœur est libre, Docker Desktop a des conditions
Il faut distinguer les composants open source de l'application de bureau Docker Desktop.| Composant | Licence | Gratuit ? |
|---|---|---|
| Docker Engine (dockerd, CLI) | Apache 2.0 | Oui, sans condition |
| Docker Compose (plugin) | Apache 2.0 | Oui, sans condition |
| Docker Desktop | Propriétaire | Sous conditions |