Docker : Maîtriser les Containers et Révolutionner votre Déploiement
Découvrez comment Docker transforme la façon de développer et déployer des applications en utilisant des conteneurs légers et portables. Ce cours vous permet de comprendre les fondamentaux des containers et de leur écosystème sans aucune connaissance préalable.
1. Introduction à Docker et aux Containers
Définition
Un container est une unité logicielle légère qui encapsule une application avec tous ses dépendances (code, runtime, bibliothèques, fichiers de configuration) dans un environnement isolé. Docker est une plateforme qui permet de créer, construire, tester et déployer facilement ces containers.
Analogie Simple
Imaginez que vous cuisinez un plat spécial. Sans container, vous devriez expliquer à chaque ami comment préparer ce plat avec les mêmes ingrédients, outils et technique - c'est compliqué et source d'erreurs. Avec Docker (le container), vous livrez une "boîte hermétiquement fermée" contenant exactement tout ce qu'il faut : ingrédients mesurés, ustensiles, recette précise. Votre ami reçoit la boîte et n'a qu'à "l'exécuter" - c'est garanti de fonctionner identiquement.
Tableau Comparatif : Approche Traditionnelle vs Docker
| Aspect | Approche Traditionnelle | Avec Docker |
|---|---|---|
| Environnement | Variables selon les machines | Identique partout |
| Installation | Manuelle et répétitive | Automatisée dans une image |
| Isolation | Partage global du système | Isolée par container |
| Performance | Surcharge complète du système | Léger et rapide |
| Portabilité | "Ça marche chez moi..." | Fonctionne partout |
| Temps déploiement | Plusieurs heures | Quelques secondes |
Astuce Pédagogique
Pour mémoriser, retenez "DCP" : Docker = Conteneur Portable. Trois mots pour trois avantages : encapsulation, cohérence, mobilité.
Attention⚠️
Docker n'est pas une machine virtuelle complète. Elle ne simule pas un système d'exploitation entier - elle partage le kernel Linux avec l'hôte. C'est sa force (légèreté) mais aussi sa limite (ne fonctionne que sur Linux nativement, Windows/Mac utilisent une VM légère).
2. Concepts Fondamentaux : Images et Containers
Définition
Une image Docker est un modèle immuable (lecture seule) contenant tous les éléments nécessaires pour exécuter une application. Un container est une instance en exécution d'une image - c'est la version "active" et modifiable. La relation image/container est similaire à la relation classe/objet en programmation orientée objet.
Analogie Simple
L'image est comme une recette photographiée et imprimée dans un livre - elle ne change jamais. Le container est comme le gâteau que vous préparez en utilisant cette recette - vous pouvez le modifier, le manger, en préparer plusieurs différents à partir de la même recette.
Tableau : Différences Image vs Container
| Caractéristique | Image | Container |
|---|---|---|
| État | Statique, immuable | Dynamique, modifiable |
| Taille | Plus grande (répertoire complet) | Plus légère (couche active) |
| Création | Construction (build) | Instanciation (run) |
| Persistance | Permanente | Disparaît si supprimée |
| Modification | Nouveau build nécessaire | Changements temporaires possibles |
| Partage | Facile à distribuer | Propre à chaque exécution |
| Utilisation CPU/RAM | Aucune avant exécution | Consomme pendant l'exécution |
Astuce Pédagogique
Gardez en tête cette formule : Image = Template inerte + Container = Instance vivante. Quand vous lancez "docker run", vous créez un container À PARTIR d'une image.
Attention⚠️
Les modifications faites dans un container en exécution ne sont pas enregistrées dans l'image. Si vous arrêtez le container, ces changements sont perdus. Pour persister les données, il faut utiliser des volumes ou créer une nouvelle image.
3. Architecture et Composants de Docker
Définition
L'architecture Docker fonctionne selon un modèle client-serveur. Le Docker Engine (le serveur) gère les containers, images et volumes. Le Docker Client (interface en ligne de commande) envoie des instructions au daemon Docker via une API REST. Ces composants travaillent ensemble pour orchestrer le cycle de vie des containers.
Analogie Simple
Imaginez une usine automobile. Docker Engine est l'usine elle-même avec ses machines. Docker Client est le directeur qui donne des ordres. L'API REST est le système de communication entre le directeur et l'usine. Les images sont les plans des voitures et les containers sont les voitures assemblées et en circulation.
Tableau : Composants Majeurs de Docker
| Composant | Rôle | Interaction |
|---|---|---|
| Docker Engine | Crée et gère containers/images | Reçoit les commandes |
| Docker Daemon | Processus serveur en arrière-plan | Exécute l'Engine |
| Docker CLI (Client) | Interface ligne de commande | Envoie des ordres |
| REST API | Communication entre client et daemon | Protocole de dialogue |
| Registries | Dépôts d'images (Docker Hub, etc.) | Stockage centralisé |
| Networking | Gère la communication entre containers | Connecte les containers |
| Storage (Volumes) | Persiste les données | Lie données à l'hôte |
Astuce Pédagogique
Utilisez cette commande mentale : CLI → API → Daemon → Engine. Quatre niveaux qui lient votre requête à l'exécution réelle.
Attention⚠️
Le Docker Daemon tourne avec les privilèges root (administrateur). Si quelqu'un a accès au socket Docker, il peut prendre le contrôle de votre machine. Ne partagez pas facilement l'accès au Docker socket, surtout en production.
4. Le Dockerfile : Plans de Construction
Définition
Un Dockerfile est un fichier texte contenant une série d'instructions qui définissent comment construire une image Docker. Chaque instruction ajoute une couche (layer) à l'image. Le processus de construction crée une image finale en empilant ces couches une par une, créant un système d'emballage reproductible et versionnable.
Analogie Simple
Un Dockerfile est comme une recette détaillée pour un plat. Chaque ligne est une étape : "Prenez de la farine" (FROM - l'image de base), "Mélangez les ingrédients" (RUN - exécuter des commandes), "Installez les épices" (RUN - installer les dépendances), "Mettez le four à préchauffer" (EXPOSE - exposer les ports), "Servez chaud" (CMD - commande de démarrage).
Tableau : Instructions Dockerfile Essentielles
| Instruction | Fonction | Exemple |
|---|---|---|
| FROM | Image de base | FROM ubuntu:20.04 |
| RUN | Exécute des commandes | RUN apt-get install python3 |
| COPY/ADD | Copie fichiers | COPY app.py /app/ |
| WORKDIR | Répertoire de travail | WORKDIR /app |
| EXPOSE | Expose un port | EXPOSE 8080 |
| ENV | Variables d'environnement | ENV NODE_ENV=production |
| CMD | Commande par défaut | CMD ["python", "app.py"] |
| ENTRYPOINT | Point d'entrée | ENTRYPOINT ["./start.sh"] |
Astuce Pédagogique
Mémorisez les trois essentielles : FROM (base), RUN (installation), CMD (exécution). 90% des Dockerfiles utilisent surtout ces trois.
Attention⚠️
Chaque instruction RUN crée une nouvelle couche. Combinez plusieurs commandes en une seule ligne avec "&& " pour réduire la taille de l'image finale. Les images mal construites peuvent devenir très volumineuses rapidement.
5. Registries Docker et Distribution d'Images
Définition
Un registry Docker est un service centralisé qui stocke, distribue et gère les images Docker. Docker Hub est le registry public par défaut maintenu par Docker Inc., mais vous pouvez créer des registries privés. Les registries permettent de versionner les images, de les partager entre équipes et de les déployer à grande échelle sur différentes machines.
Analogie Simple
Un registry Docker est comme un dépôt de librairie ou un musée. Docker Hub est la grande bibliothèque publique où tout le monde peut consulter et emprunter des livres (images). Vous pouvez aussi créer votre propre petite bibliothèque privée (registry privé) dans votre entreprise où seulement les employés autorisés peuvent accéder aux livres spécialisés.
Tableau : Types de Registries et Caractéristiques
| Type | Accès | Contrôle | Coût | Cas d'Usage |
|---|---|---|---|---|
| Docker Hub Public | Public/Gratuit | Docker Inc. | Gratuit | Développement, images open source |
| Docker Hub Privé | Authentification | Propriétaire | Payant | Équipes, code propriétaire |
| Registry Privé Auto-hébergé | Contrôlé | Complètement vôtre | Infrastructure | Entreprise, contrôle total |
| Registries Cloud (AWS ECR, Azure) | Cloud contrôlé | Propriétaire | Payant | Intégration cloud, CI/CD |
| Registries GitHub/GitLab | Avec repo Git | Git intégré | Gratuit/Payant | Développeurs utilisant Git |
Astuce Pédagogique
Pensez "Pull & Push" : vous "pullz" (téléchargez) des images du registry pour les utiliser, et vous "pushez" (uploadez) vos images crées pour les partager.
Attention⚠️
Ne versionnez jamais des images avec le tag "latest" en production - c'est imprévisible. Toujours utiliser des versions explicites (v1.0.0, v2.1.5). Une image sans version tag reçoit "latest" par défaut, ce qui peut causer des déploiements non contrôlés si l'image change.
6. Volumes et Gestion des Données
Définition
Les volumes Docker sont des mécanismes de stockage persistant qui permettent à un container d'accéder à des données stockées sur la machine hôte ou dans un espace géré par Docker. Contrairement aux fichiers à l'intérieur du container (qui disparaissent à l'arrêt), les volumes survivent au cycle de vie du container et permettent le partage de données entre containers et l'hôte.
Analogie Simple
Un container sans volume est comme une chambre d'hôtel : tout ce que vous laissez dedans disparaît quand vous partez. Un volume est comme un coffre-fort verrouillé dans la réception : vos données y sont stockées en sécurité, et vous pouvez les récupérer même après avoir quitté la chambre. Vous pouvez même partager ce coffre avec d'autres clients (containers).
Tableau : Types de Montage de Données
| Type | Source | Destination | Persistance | Partage | Complexité |
|---|---|---|---|---|---|
| Volume nommé | Géré par Docker | Chemin container | Persistant | Multi-containers | Simple |
| Bind Mount | Dossier hôte | Chemin container | Synchronisé | Hôte + container | Moyen |
| tmpfs Mount | Mémoire RAM | Chemin container | Temporaire | Pas de partage | Simple |
| Network Share | Serveur réseau | Chemin container | Persistant | Multi-machines | Complexe |
Astuce Pédagogique
Utilisez des volumes nommés par défaut - c'est plus sûr et géré par Docker. Le Bind Mount est utile en développement (changer du code et voir les changements directement), mais moins idéal en production.
Attention⚠️
Les données dans un container sans volume sont perdues définitivement à la suppression du container. C'est une source fréquente de pertes de données. Toujours mettre en place des volumes pour les données importantes (bases de données, fichiers utilisateur, etc.).
7. Networking : Communication entre Containers
Définition
Le networking Docker permet aux containers de communiquer entre eux et avec l'extérieur. Docker fournit plusieurs types de réseaux (bridge, host, overlay) qui définissent comment les containers sont connectés et isolés. Chaque container peut avoir une adresse IP, et les réseaux permettent une communication sécurisée et isolée entre services.
Analogie Simple
Imaginez une ville avec plusieurs restaurants (containers). Sans réseau Docker, chaque restaurant est isolé du monde. Avec un réseau Docker, les restaurants sont tous situés dans la même rue (réseau bridge) et peuvent communiquer entre eux - les clients peuvent aller d'un restaurant à l'autre. Le réseau host, c'est comme mettre les restaurants directement dans la ville réelle - plus rapide mais moins isolé.
Tableau : Types de Réseaux Docker
| Type | Portée | Isolation | Performance | Cas d'Usage | Complexité |
|---|---|---|---|---|---|
| Bridge | Hôte local | Bonne | Très bonne | App simple, multi-containers locaux | Facile |
| Host | Hôte | Nulle | Excellente | Performance critique | Moyen |
| Overlay | Multi-hôte | Bonne | Bonne | Swarm, orchestration distribuée | Complexe |
| Macvlan | Multi-hôte | Parfaite | Excellente | Besoin IP distincte | Très complexe |
| None | Aucun | Complète | N/A | Container isolé | Très facile |
Astuce Pédagogique
Le "bridge" est le réseau par défaut et celui à utiliser 80% du temps pour débuter. C'est suffisant pour des développements normaux et la courbe d'apprentissage est douce.
Attention⚠️
Par défaut, les containers sur le même réseau bridge peuvent se communiquer par nom de service automatiquement grâce à DNS interne. Cependant, ce n'est pas le cas sur la "bridge par défaut" - créez toujours un réseau nommé pour bénéficier de la résolution DNS automatique entre containers.
8. Docker Compose : Orchestration Simplifiée
Définition
Docker Compose est un outil qui permet de définir et exécuter des applications multi-containers à partir d'un fichier de configuration YAML. Au lieu de lancer chaque container manuellement avec de longues commandes, vous décrivez l'ensemble de votre application (containers, volumes, réseaux, variables) dans un fichier docker-compose.yml, puis lancez tout avec une simple commande "docker-compose up".
Analogie Simple
Sans Docker Compose, lancer une application complexe est comme diriger un orchestre où chaque musicien (container) doit arriver à l'heure exacte, avoir les bons instruments (volumes, ports, variables) et connaître sa partition. C'est le chaos. Docker Compose est le chef d'orchestre avec un partochage écrit : tout est synchronisé, chacun sait quand entrer et comment se connecter aux autres.
Tableau : Structure de Base d'un docker-compose.yml
| Section | Fonction | Éléments | Exemple |
|---|---|---|---|
| version | Version de la syntaxe | "3.8", "3.9" | version: '3.8' |
| services | Containers à lancer | Web, DB, Cache | web: (service définition) |
| volumes | Stockage persistant | Nommé, bind | volumes: db_data: |
| networks | Réseaux créés | Personnalisés | networks: backend: |
| environment | Variables globales | Clés-valeurs | environment: NODE_ENV |
Astuce Pédagogique
Pensez docker-compose.yml comme un "manifeste d'application entière". Une ligne de YAML = une configuration qui aurait pris 3-4 drapeaux Docker CLI. C'est une économie énorme.
Attention⚠️
Docker Compose est excellent pour le développement et les petits déploiements, mais ne convient pas pour l'orchestration de production à grande échelle. Pour cela, utilisez Kubernetes. Aussi, les secrets sensibles ne doivent jamais être en clair dans docker-compose.yml - utilisez des fichiers .env ou des systèmes de secrets.
9. Bonnes Pratiques et Optimisation des Images
Définition
Les bonnes pratiques Docker concernent la construction optimale des images, la sécurité, les performances et la maintenabilité. Cela inclut : utiliser des images de base légères, réduire les couches, utiliser les .dockerignore, scanner les vulnérabilités, ne pas exécuter root, utiliser des tags appropriés, et documenter les images. Une image bien construite est petite, rapide, sécurisée et facile à maintenir.
Analogie Simple
Construire une image Docker c'est comme construire une maison. Les mauvaises pratiques : utiliser des matériaux de mauvaise qualité (image de base complète), accumuler les déchets (couches inutiles), laisser les portes ouvertes (exécuter root), ne pas inspecter les fondations (ignorer les vulnérabilités). Les bonnes pratiques : matériaux de qualité (image Alpine), nettoyer après chaque étape, fermer les portes (utilisateur non-root), inspecter régulièrement.
Tableau : Comparaison Mauvaises vs Bonnes Pratiques
| Aspect | ❌ Mauvaise Pratique | ✅ Bonne Pratique | Impact |
|---|---|---|---|
| Image de base | ubuntu:latest (1.2GB) | alpine:3.14 (40MB) | 30x plus léger |
| Couches | 20+ commandes RUN | 3-4 RUN optimisés | Réduction taille |
| Root | Exécution par root | Utilisateur dédié | Sécurité |
| Secrets | Codes en dur dans Dockerfile | Variables d'env, secrets | Protection données |
| Tagging | Pas de tag ou "latest" | Versions explicites | Contrôle versions |
| Scanning | Aucun | Scan vulnérabilités régulier | Sécurité production |
| Docs | Aucune | README, commentaires | Maintenabilité |
Astuce Pédagogique
Retenez "LSSU" : Léger, Sécurisé, Signé, Unique. Quatre critères pour juger une bonne image Docker.
Attention⚠️
Ne déployez jamais une image avec le tag "latest" en production - vous ne savez pas exactement quelle version s'exécute. Utilisez des tags de version sémantique (v1.2.3). De plus, exécuter un container en tant que root est un risque de sécurité majeur - si l'application est compromise, l'attaquant a accès root à la machine. Toujours créer un utilisateur non-privilégié.
10. Déploiement et Cycle de Vie en Production
Définition
Le déploiement Docker en production implique de prendre une application conteneurisée développée et testée localement, puis de la mettre en ligne sur des serveurs de production. Cela nécessite une compréhension des concepts comme la résilience (restart policies), la scalabilité (réplication), la santé des containers (health checks), et l'orchestration (Docker Swarm ou Kubernetes) pour gérer des déploiements robustes et maintenables à long terme.
Analogie Simple
Déployer localement sur votre ordinateur c'est faire un gâteau pour vous-même : vous contrôlez tout et si quelque chose casse, vous êtes seul impacté. Déployer en production c'est comme ouvrir une boulangerie : le gâteau doit être disponible 24/7, il doit être délicieux systématiquement, si une machine tombe en panne d'autres prennent le relais, et vous devez pouvoir augmenter la production si la demande augmente.
Tableau : Considérations Production vs Développement
| Aspect | Développement | Production |
|---|---|---|
| Nombre containers | 1-10 | 10-10000+ |
| Disponibilité | Best-effort | 99.9%+ SLA |
| Restart automatique | Optionnel | Critique |
| Health checks | Non | Essentiel |
| Logs | Stdout | Centralisé (ELK, Splunk) |
| Monitoring | Manuel | Automatisé (Prometheus, Datadog) |
| Orchestration | Docker simple | Kubernetes, Swarm |
| Rollback | Manuel | Automatisé |
| Secrets | Fichiers | Gestionnaires dédiés |
| Mise à jour | Arrêt acceptable | Zero-downtime deployments |
| Backup données | Optionnel | Critiquement important |
| Load balancing | Pas nécessaire | Essentiel |
Astuce Pédagogique
Utilisez les "restart policies" même en développement pour vous habituer : --restart=unless-stopped relance automatiquement un container à moins que vous l'arrêtiez explicitement.
Attention⚠️
Ne mettez jamais un container en production sans restart policy définie - une application qui crash disparaîtra silencieusement. Configurez toujours restart=on-failure ou restart=unless-stopped. De plus, sans health checks, Docker ne sait pas que votre application est plantée. Implémentez toujours un endpoint de santé et configurez les health checks dans votre configuration Docker.