
Docker te permet de packager une application + ses dépendances dans une image (artefact immuable), puis de l’exécuter sous forme de conteneur (process isolé). 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) »-
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) »-
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) »| 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 |
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, 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
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é |
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.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