Docker Masterclass : Architecture, Sécurité et Haute Disponibilité
Dernière mise à jour : Janvier 2026
Parcours d'apprentissage
Partie 1 : Fondamentaux et Architecture Bas-Niveau
Partie 2 : Environnements et Contextes
Partie 3 : Cycle de Vie et Manipulation Avancée
Partie 4 : Dockerfile Expert (Construction et Optimisation)
Partie 5 : Persistance et Observabilité (Volumes & Logs)
Partie 6 : Networking et Communication Inter-services
Partie 7 : Orchestration Locale avec Docker Compose
Partie 8 : Sécurité et Durcissement (Production-Ready)
Partie 9 : Industrialisation et Multi-Architecture
Partie 10 : Troubleshooting et Cas Réels
Partie 1 : Fondamentaux (Commencer par le Pourquoi)
Chapitre 1 : Comprendre le Besoin (VM vs Conteneurs)
1.1 Le Problème : "L'Enfer des Dépendances"
Avant Docker, déployer une application était un cauchemar. Le développeur codait sur son Mac avec Python 3.9, mais le serveur de production tournait sous Debian avec Python 3.6.
"Mais ça marche sur ma machine !" ¯\_(ツ)_/¯
Résultat : Des conflits de librairies, des versions différentes, et des heures perdues à debugger l'environnement plutôt que le code.
1.2 La 1ère Solution : La Machine Virtuelle (VM)
Pour isoler les applications, on utilisait des machines virtuelles (VMware, VirtualBox). Chaque application avait son propre ordinateur virtuel complet.
- Avantage : Isolation totale.
- Inconvénient majeur : Gaspillage énorme. Pour faire tourner une petite app Node.js de 10 Mo, on devait lancer un OS entier (Windows/Linux) qui prend 2 Go de RAM et 20 Go de disque.
1.3 La Révolution Docker : Le Conteneur
Docker a démocratisé le Conteneur. Au lieu de virtualiser le matériel (comme une VM), on partage le noyau du système hôte (Linux), mais on isole les processus.
Chaque locataire a sa PROPRE maison (fondations, murs, toit). Très cher, très lourd.
Tout le monde vit dans le MÊME immeuble (Même Noyau), mais chacun a sa chambre clé en main (Isolation).
1.4 Comment est-ce possible ? (L'Isolation Linux)
Docker n'invente rien, il utilise des briques Linux existantes pour créer cette illusion de chambre privée :
C'est ce qui cache les voisins.
Ex: Le PID Namespace fait croire au conteneur qu'il est le seul processus (PID 1) sur la machine.
C'est ce qui rationne la nourriture.
Ils empêchent un conteneur de manger toute la RAM ou le CPU au détriment des autres.
🛠️ Exercice de pensée
Ouvrez votre gestionnaire de tâches (si vous êtes sur Windows) ou `htop` (Linux).
Dans une VM, vous ne verriez pas les processus de l'invité.
Avec Docker, les processus des conteneurs SONT des processus normaux sur votre machine, juste "déguisés" et limités.
Chapitre 2 : Le système de fichiers UnionFS
Le Miracle de l'Héritage
Si je lance 100 conteneurs Ubuntu, est-ce que je copie 100 fois Windows ? Non. Docker utilise un système de calques (Layers).
- Tous vos conteneurs partagent la même image de base en lecture seule (Le socle).
- Chaque conteneur n'écrit que ses petites modifications sur une fine couche au-dessus.
Copy-on-Write (CoW)
Si vous ne touchez pas à un fichier, Docker lit l'original. Si vous le modifiez, Docker en crée une copie juste pour vous à la volée. C'est ultra-rapide et économise l'espace.
Chapitre 3 : Qui fait quoi ? (Architecture)
| Composant | Analogie Restaurant |
|---|---|
| Docker Client (CLI) | Le client qui passe commande (Menu). |
| Docker Daemon | Le Chef de salle qui prend la commande et gère la salle. |
| containerd | Le Cuisinier en chef qui supervise la préparation. |
| runc | Le commis qui assemble réellement le plat (le conteneur). |
Partie 2 : Environnements et Contextes
Chapitre 1 : Architecture Docker sous Windows
1.1 Hyper-V vs WSL 2
Historiquement, Docker Desktop utilisait une grosse VM Hyper-V classique (lente au démarrage, allocation RAM fixe).
Aujourd'hui, WSL 2 (Windows Subsystem for Linux 2) est la norme :
- Noyau Linux réel : Microsoft livre un vrai kernel Linux optimisé.
- Dynamic RAM : La VM prend de la RAM quand elle en a besoin et la rend à Windows quand elle a fini.
- Intégration Fichiers : Accès direct aux fichiers Linux depuis l'explorateur Windows (`\\wsl$\`).
Exercice : Vérifier son installation
Vérifions que votre moteur Docker est bien connecté à WSL 2 et fonctionnel. Exécutez ces commandes dans PowerShell ou Terminal.
Si vous voyez une erreur "error during connect: ... Is the docker daemon running?", lancez Docker Desktop d'abord.
Dans la sortie de docker version, section "Server", vous devriez voir OS/Arch: linux/amd64. C'est la preuve que votre Docker tourne bien dans une VM Linux (WSL), même si vous êtes sous Windows.
Chapitre 2 : Interface Graphique vs Ligne de Commande
Le Dashboard (GUI)
Docker Desktop offre une interface visuelle très pratique.
- Voir les logs en un clic.
- Ouvrir un terminal dans le conteneur ("Exec").
- Voir la consommation CPU/RAM visuelle.
- Supprimer rapidement volumes et images.
Le CLI (Terminal)
La vraie puissance réside ici.
- Automatisation via scripts bash.
- Utilisation universelle sur serveurs Linux (qui n'ont pas d'écran).
- Options avancées cachées dans l'interface graphique.
Chapitre 3 : Docker Contexts (Gérer le Multi-Environnement)
Par défaut, la commande `docker` parle au socket local `/var/run/docker.sock` (ou pipe Windows). Mais saviez-vous qu'elle peut piloter un Docker situé sur un serveur à l'autre bout du monde via SSH ?
Exercice Avancé : Simulation de Remote Docker
Nous allons créer un contexte. Disons que vous avez un serveur avec l'IP 192.168.1.55 et l'utilisateur admin.
Pour que cela fonctionne, vous devez avoir configuré l'authentification SSH par clé (Key-based auth) sans mot de passe vers le serveur distant. Sinon, Docker demandera le mot de passe à chaque commande, ce qui cassera les scripts.
Partie 3 : Cycle de Vie et Manipulation Avancée
Chapitre 1 : Le Cycle de Vie d'un Conteneur
La Machine à États
Pour passer d'un état à l'autre, on utilise les verbes d'action Docker :
- create : Télécharge l'image et prépare le conteneur (ne lance pas le processus).
- start : Lance le processus (PID 1). Passe à l'état Running.
- run : Combo magique de
create+start. - pause / unpause : Gèle le processus en mémoire (SIGSTOP).
- stop : Arrêt gracieux (SIGTERM). Passe à l'état Exited.
- kill : Arrêt brutal (SIGKILL).
- rm : Supprime le conteneur Exited (libère le disque).
Exercice : Maîtriser le cycle de vie
Lancez un serveur web Nginx, vérifiez qu'il tourne, arrêtez-le et supprimez-le. Suivez les instructions.
Vous avez la flemme de faire stop puis rm ?
Utilisez docker rm -f mon-web pour forcer la suppression d'un conteneur en cours d'exécution (envoie un SIGKILL). À utiliser avec précaution en prod !
Chapitre 2 : Récupération et Debugging Avancé
Cas d'école : Le conteneur qui crashe immédiatement
Vous lancez un conteneur et boum, il disparaît. docker ps ne le montre pas.
La commande docker logs [id] est votre premier réflexe, mais parfois vous voulez voir les fichiers à l'intérieur pour comprendre (ex: un fichier de config corrompu).
Mais comment entrer dans un conteneur arrêté ? (Spoiler: on ne peut pas faire docker exec sur un conteneur éteint).
La Solution : docker cp
L'outil cp marche même sur les conteneurs arrêtés ! Il permet d'extraire des fichiers "post-mortem".
Exercice Simulation de Panne
Nous allons créer un fichier dans un conteneur éphémère et essayer de le récupérer après sa mort.
Le système de fichiers d'un conteneur persiste même après l'arrêt du processus. Tant que vous ne faites pas docker rm, toutes les données modifiées dans la couche inscriptible sont là, accessibles via docker cp ou docker export.
Chapitre 3 : Maintenance et Nettoyage (Prune)
La commande docker system prune est puissante mais dangereuse.
| Commande | Effet | Dangerosité |
|---|---|---|
| docker container prune | Supprime tous les conteneurs STOPPÉS. | Faible |
| docker image prune | Supprime les images "dangling" (sans tag, |
Faible |
| docker system prune -a | Supprime TOUTES les images non utilisées par un conteneur actif. | Élevée (Re-téléchargement nécessaire) |
| docker volume prune | Supprime les volumes non attachés. Adieu les données ! | CRITIQUE |
Partie 4 : Dockerfile Expert
Chapitre 1 : Syntaxe Avancée (Best Practices)
-
WORKDIR vs RUN cd :
Ne faites jamaisRUN cd /app. Ça ne marche pas comme vous pensez car chaque RUN démarre un nouveau shell.
Utilisez toujoursWORKDIR /app. Si le dossier n'existe pas, il est créé. -
ENV vs ARG :
ARG (Build-time)
Variables disponibles uniquement pendant la construction de l'image.
Ex:ARG VERSION=1.0ENV (Run-time)
Variables qui restent dans l'image finale et le conteneur.
Ex:ENV NODE_ENV=production -
Gestion du Cache : Docker met en cache chaque ligne. Ordonnez vos instructions du moins changeant au plus changeant. Copiez les
package.jsonAVANT de copier le code source !
Exercice : Optimiser le Cache
Voici un Dockerfile mal optimisé. À chaque fois que vous changez une ligne de code, `npm install` se relance (long !). Comment le corriger ?
Pourquoi ? Si vous modifiez `index.js`, Docker voit que `package.json` n'a pas bougé. Il utilise donc le cache du layer `RUN npm install`. Build instantané !
Chapitre 2 : Le problème du PID 1 & Signaux
Le Piège du Shell Form
Il existe deux façons d'écrire CMD et ENTRYPOINT. Une seule est correcte pour la production.
CMD node app.js
Docker lance /bin/sh -c "node app.js". Le PID 1 est `sh`, pas `node`. Les signaux d'arrêt sont ignorés.
CMD ["node", "app.js"]
L'exécutable est lancé directement. Il reçoit le SIGTERM proprement.
La Solution "Tini"
Parfois, votre application (ex: Java) ne sait pas gérer les signaux Docker même en Exec Form. La solution est d'utiliser un init process comme tini.
Avec `docker run --init`, Docker injecte tini automatiquement sans modifier l'image.
Chapitre 3 : Multi-stage Build (Réduire la taille)
Pourquoi livrer les compilateurs (GCC, Maven, Go) en production ? Ils ne servent qu'au build.
Le Multi-stage build permet d'avoir une image temporaire de build, et de copier le résultat dans une image finale minuscule.
Exercice : Comprendre le Multi-stage
Image Golang standard : ~800 Mo
Image Alpine finale : ~10 Mo
Gain : 98% !
Partie 5 : Persistance et Observabilité
Chapitre 1 : Stratégies de Stockage
Bind Mounts
Un chemin exact de l'hôte est monté dans le conteneur.
- Dépendance : Dépend de l'OS et du chemin de l'hôte.
- Usage : Développement (Hot reload).
- Perf : Moins bonne sous Windows/Mac (Filesystem crossing).
Volumes Nommés
Docker gère le stockage dans /var/lib/docker/volumes.
- Dépendance : Indépendant de l'OS hôte.
- Usage : Production (Databases).
- Perf : Native (même sous WSL 2).
Exercice : Survivre à la suppression
Prouvons que les données survivent à la suppression du conteneur grâce aux volumes.
Le second conteneur affiche Solde: 1M€. Vos données sont sauves !
Chapitre 2 : Maîtriser les Logs
Pourquoi la rotation est vitale ?
Par défaut, un conteneur qui tourne depuis 6 mois peut avoir un fichier JSON de logs de 50 Go. Si votre disque sature, tout le serveur plante.
La configuration se fait soit globalement (daemon.json) soit par conteneur.
Configuration Docker Compose
Copiez ce bloc dans tous vos services de production.
Résultat : Votre conteneur ne prendra jamais plus de 30 Mo de logs disque.
Partie 6 : Networking Avancé
Chapitre 1 : DNS et Communication Inter-Conteneurs
La magie du `127.0.0.11`
Chaque conteneur a dans son /etc/resolv.conf une entrée pointant vers un serveur DNS interne de Docker.
C'est ce qui permet de faire ping mysql au lieu de ping 172.18.0.4.
bridge par défaut. Vous DEVEZ créer vos propres réseaux.
Exercice : Le test du Ping
Prouvons la différence entre Bridge par défaut et User-defined bridge.
Sur le réseau mon-net, le ping répond ! Docker a automatiquement enregistré "c2" dans son DNS interne. C'est essentiel pour que votre API trouve sa base de données sans connaître son IP.
Chapitre 2 : Exposition des Ports
Port Mapping (-p)
-p 8080:80 ouvre une brèche dans le réseau hôte. Tout le trafic arrivant sur le port 8080 de votre machine physique est redirigé vers le port 80 du conteneur.
Expose (Documentation)
Sert uniquement pour la documentation et pour l'option -P (mappage aléatoire). N'ouvre rien techniquement.
Chapitre 3 : Isolation Réseau (Architecture 3-tiers)
En production, on n'expose pas tout à tout le monde.
Le Design Pattern "Backend Invisible"
# docker-compose.yml (extrait)
services:
frontend:
# Visible depuis Internet
ports: ["80:80"]
networks:
- front-net
api:
# Visible seulement par le frontend
expose: ["3000"] # Pas de ports mappés !
networks:
- front-net
- back-net
db:
# Visible seulement par l'API (totalement isolée)
networks:
- back-net
networks:
front-net:
back-net:
internal: true # Pas d'accès internet sortant (optionnel)
Partie 7 : Orchestration Locale avec Docker Compose
Chapitre 1 : L'Infrastructure as Code (IaC)
Docker Compose transforme vos lignes de commandes docker run interminables en un fichier de configuration élégant et versionné.
Exercice : Votre première stack LAMP
Objectif : Définir un serveur Web (Apache/PHP) et une base de données MySQL qui se parlent.
docker-compose up -d : Démarre tout (crée réseau, volumes, conteneurs).
docker-compose ps : Vérifie l'état.
docker-compose logs -f : Suit les logs de tous les services mélangés (très pratique !).
docker-compose down : Tout éteindre et nettoyer (sauf les volumes).
Chapitre 2 : La course au démarrage (Race Conditions)
Le problème "Connection Refused"
Dans l'exercice précédent, PHP démarre en 100ms, mais MySQL met 5 à 10 secondes à s'initialiser.
Si PHP tente de se connecter tout de suite, il plante.
Ajouter depends_on: [database] ne suffit pas ! (Ça attend juste que le conteneur soit créé, pas que MySQL soit prêt).
La Solution Robuste
Chapitre 3 : Gestion Sécurisée des Variables (.env)
Ne commitez jamais vos mots de passe sur Git. Utilisez l'interpolation de variables.
Exercice : Sécuriser sa stack
Séparez la config du code.
Lancez docker-compose config.
Cette commande vous montre le YAML final généré. Vous verrez que Docker a bien remplacé ${DB_PASS} par la vraie valeur.