🐳 Docker Deep Dive
Containers, Images & Orchestration Locale
🍰 Analogie : Le Gâteau Mille-Feuille
Une image Docker est un gâteau à étages (Layers). Chaque instruction RUN,
COPY ajoute une couche.
Si vous changez la cerise (code), on ne recuit pas tout le gâteau, on change juste la dernière
couche.
L'optimisation, c'est mettre les ingrédients lourds (OS, Deps) en bas, et les légers (Code)
en haut.
📖 Docker : La fin de la "Matrix of Hell"
Avant Docker, déployer une application était un cauchemar de compatibilité (la Matrix of Hell). On devait s'assurer que l'App A (Python 2.7) ne cassait pas l'App B (Python 3.5) sur le même serveur. Docker a apporté l'Isolation Hermétique.
Le concept clé : "Build once, run anywhere". Le package contient tout : code, runtime, bibliothèques, variables d'environnement. Si ça marche sur votre laptop, ça marchera en prod.
💡 Le saviez-vous ? La naissance d'une révolution
En mars 2013, à la conférence PyCon, Solomon Hykes présente un projet interne de sa startup dotCloud : Docker. La démo de 5 minutes scotche l'assistance : lancer un container en moins d'une seconde. L'année d'après, dotCloud devient Docker Inc., et change le monde de l'IT pour toujours.
Aujourd'hui, Docker est l'unité de mesure de base du DevOps.
🏗️ A. Architecture Docker
Image vs Container
- Image = Recette (figée, versionnée, read-only)
- Container = Gâteau (instance vivante et éphémère de l'image)
- 1 Image → N Containers identiques
🥊 B. Machine Virtuelle (VM) vs Conteneur
🖥️ Machine Virtuelle (VM)
- Isolation forte : Matérielle (Hyperviseur).
- OS Complet : Chaque VM embarque son propre système d'exploitation (Guest OS).
- Poids : Lourd (plusieurs Gigaoctets).
- Démarrage : Lent (quelques minutes).
- Cas d'usage : Exécuter des OS différents, isolation de sécurité maximale.
🐳 Conteneur (Docker)
- Isolation logique : Processus (Namespaces, Cgroups).
- Partage kernel : Tous les conteneurs partagent l'OS de l'hôte (Host OS).
- Poids : Très léger (quelques Mégaoctets).
- Démarrage : Instantané (quelques millisecondes/secondes).
- Cas d'usage : Microservices, CI/CD, scalabilité rapide, standardisation.
📜 B. Instructions Dockerfile
| Instruction | Rôle | Exemple |
|---|---|---|
FROM |
Image de base (obligatoire en 1er) | FROM node:20-alpine |
WORKDIR |
Définit le dossier de travail | WORKDIR /app |
COPY |
Copie fichiers locaux → image | COPY package*.json ./ |
RUN |
Exécute une commande (Build Time) | RUN npm install |
ENV |
Définit une variable d'environnement | ENV NODE_ENV=production |
EXPOSE |
Documente le port (ne l'ouvre pas !) | EXPOSE 3000 |
CMD |
Commande par défaut au run | CMD ["node", "server.js"] |
ENTRYPOINT |
Point d'entrée fixe (CMD = arguments) | ENTRYPOINT ["python"] |
# --- Build Stage --- FROM node:20-slim AS builder WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . RUN npm run build # --- Run Stage (Distroless) --- FROM gcr.io/distroless/nodejs20-debian12 WORKDIR /app COPY --from=builder /app/dist ./dist CMD ["dist/main.js"]
Best Practices (2025)
- Multi-Stage : Compile dans une image "grosse", run dans une "minuscule"
- .dockerignore : Exclure
node_modules,.git - USER : Ne jamais run en root (
USER 1001) - Layers : Mettre les deps avant le code (cache)
🎼 C. Docker Compose (Multi-Services)
version: '3.8' services: app: build: . ports: - "3000:3000" environment: - DATABASE_URL=postgres://db:5432 depends_on: - db db: image: postgres:15 volumes: - pgdata:/var/lib/postgresql/data environment: POSTGRES_PASSWORD: secret volumes: pgdata:
Concepts Clés
- services : Chaque conteneur est un service
- ports : Mappage Hôte → Container
- volumes : Persistence des données
- depends_on : Ordre de démarrage
docker compose up -d pour lancer en background.
⌨️ D. Commandes CLI Essentielles
| Commande | Action |
|---|---|
docker build -t myapp . |
Construire une image depuis le Dockerfile |
docker run -d -p 8080:80 nginx |
Lancer un container en arrière-plan |
docker ps |
Lister les containers actifs |
docker logs -f <id> |
Suivre les logs en temps réel |
docker exec -it <id> sh |
Ouvrir un shell dans le container |
docker stop <id> |
Arrêter un container |
docker rm <id> |
Supprimer un container arrêté |
docker system prune -a |
⚠️ Nettoyer tout (images, containers, volumes orphans) |
🛑 Troubleshooting : Le Container quitte immédiatement (Exit 0)
- Symptôme : Vous lancez
docker run -d ubuntu, maisdocker psne montre rien.docker ps -amontre que le container est "Exited (0)". - Diagnostic : Un container Docker ne reste en vie que tant que son processus principal (PID 1) tourne. L'image de base Ubuntu démarre avec "/bin/bash" par défaut. Sans terminal interactif attaché, bash se termine aussitôt, et donc le container s'arrête.
- Remède : Pour garder un container en vie "pour rien", ajoutez une tâche bloquante comme
tail -f /dev/nullou utilisezdocker run -dit ubuntupour l'attacher à un TTY interactif en arrière-plan.
⚡ E. Modern Build (BuildKit)
Depuis Docker 18.09, BuildKit est le moteur de build par défaut. Il permet des builds parallélisés, plus sûrs et plus rapides grâce au cache intelligent.
# Syntax directive (facultatif mais recommandé) # syntax=docker/dockerfile:1 FROM node:20-alpine WORKDIR /app # Mount Cache : Accélère npm ci x10 RUN --mount=type=cache,target=/root/.npm \ npm ci # Mount Secret : Clé SSH sécurisée RUN --mount=type=secret,id=ssh_key \ git clone git@github.com:priv/repo.git CMD ["node", "app.js"]
- Concurrent Build : Si 2 étapes ne dépendent pas l'une de l'autre, elles se lancent EN MÊME TEMPS.
- Secrets : Les secrets montés ne sont JAMAIS persistés dans l'image finale (contrairement à COPY).
- Cache Mounts : Garde le dossier
node_modulesou.m2entre les builds.
🛡️ F. Sécurité & Optimisation
Distroless
Images Google contenant uniquement l'app et ses deps runtime. Pas de Shell, pas
de
package manager, pas de ls. Surface d'attaque minimale.
Scanning (Trivy)
Scanner les CVEs (failles connues) avant de push.trivy image myapp:latest
Rootless
Ne JAMAIS faire tourner en root.
Ajouter USER node ou USER 1001 à la
fin
du Dockerfile.
🌐 G. Docker Context
Comment contrôler un Docker sur un serveur distant (prod) depuis son laptop sans ouvrir le port 2375
(dangereux) ?
Réponse : Docker Context over SSH.
$ docker context create remote-prod --docker "host=ssh://admin@192.168.1.50" $ docker context use remote-prod $ docker ps # Affiche les containers du serveur PROD, sécurisé via SSH !
📊 Cas d'étude : Spotify - L'Autonomie à l'échelle
Challenge : Comment permettre à 500 équipes de déployer sans qu'une équipe "Ops" centrale ne devienne un goulot d'étranglement ?
Solution : Golden Paths.
- Spotify fournit des "Golden Paths" (Templates Dockerfile + Pipeline CI/CD pré-approuvés).
- Si une équipe utilise le Golden Path Docker, elle déploie en prod sans validation humaine.
- Si elle veut faire du custom, elle doit gérer sa propre sécurité et astreinte.
Résultat : Docker a permis de standardiser l'unité de déploiement, rendant l'autonomie possible.
🖥️ Machines Virtuelles (VM)
- Isolation Fort : Noyau OS dédié. Plus sécurisé.
- Lourd : Plusieurs Go par VM. Consomme beaucoup de RAM.
- Lent : Minutes pour démarrer.
- Cas d'usage : Isolation totale, OS différents sur un même hôte.
🐳 Containers (Docker)
- Efficace : Partage le noyau de l'hôte. Quelques Mo.
- Rapide : Millisecondes pour démarrer.
- Portabilité : Garanti le fonctionnement identique partout.
- Cas d'usage : Microservices, CI/CD, Cloud Native apps.
📊 Cas d'étude : Migration Monolithe → Microservices
Contexte : Une banque traditionnelle gérait son application de trading avec un monolithe J2EE. Les déploiements étaient si risqués qu'ils n'avaient lieu que deux fois par an.
Transformation :
- Containérisation : Migration graduelle vers Docker.
- Découpage : Séparation du front, de l'auth et du moteur de prix en micro-services Docker.
- Auto-scaling : Utilisation de Docker Swarm (puis K8s) pour gérer les pics de charge.
Résultat : Temps de mise sur le marché divisé par 24. Coût de maintenance réduit grâce à l'optimisation des ressources Docker.
🔄 À Retenir - Docker Deep Dive
- Image vs Container : L'image est le plan, le container est la maison.
- Isolation : Les containers partagent le kernel mais sont isolés.
- Dockerfile : Automatisez la création d'images. Optimisez les layers.
- Persistence : Utilisez les Volumes pour les données (DB, Logs).