
Vous avez déjà eu ce problème : « Ça marche sur ma machine, mais pas en production » ? Docker résout exactement ce casse-tête. Ce guide vous apprend à installer Docker, créer vos premiers conteneurs et construire des images personnalisées — le tout en partant de zéro.
Que vous soyez développeur, administrateur système ou simplement curieux de la conteneurisation, vous trouverez ici tout ce qu’il faut pour démarrer avec Docker et l’intégrer dans vos workflows quotidiens. Prérequis : un ordinateur (Linux, Windows ou macOS) et une connexion internet.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »Installer Docker
Installation sur Linux (Ubuntu/Debian), Windows (WSL2/Desktop) et macOS (Colima).
Gérer images et conteneurs
Commandes pull, run, ps, stop, rm — le cycle de vie complet.
Construire des images
Écrire un Dockerfile efficace et créer vos propres images.
Maintenir votre environnement
Nettoyer les ressources, surveiller, diagnostiquer les problèmes.
Qu’est-ce que Docker ?
Section intitulée « Qu’est-ce que Docker ? »Imaginez que vous déménagiez. Deux options s’offrent à vous : emballer chaque objet séparément dans des cartons de tailles différentes, ou utiliser des conteneurs standards où tout est parfaitement rangé et transportable. Docker fonctionne exactement comme ces conteneurs standards, mais pour vos applications.
Le problème que Docker résout
Section intitulée « Le problème que Docker résout »Avant Docker, déployer une application ressemblait à un parcours du combattant. Chaque serveur avait sa propre configuration, ses propres versions de bibliothèques, ses propres particularités. Le résultat ? Le fameux « ça marche chez moi » — cette phrase que tout développeur a entendue au moins une fois.
| Sans Docker | Avec Docker |
|---|---|
| L’application fonctionne sur le poste du développeur mais échoue en production | L’application fonctionne de manière identique partout |
| Chaque serveur nécessite une configuration manuelle | L’environnement est packagé avec l’application |
| Les conflits de versions de bibliothèques sont fréquents | Chaque conteneur a ses propres dépendances isolées |
| Mise à jour risquée (peut casser d’autres applications) | Conteneurs indépendants les uns des autres |
Définition simple
Section intitulée « Définition simple »Docker est une plateforme open source qui permet de packager une application avec tout ce dont elle a besoin (code, bibliothèques, configuration) dans une unité appelée conteneur. Ce conteneur peut ensuite s’exécuter de manière identique sur n’importe quel serveur où Docker est installé.
Concrètement, un conteneur est comme une boîte hermétique qui contient votre application et tout son environnement. Que vous lanciez cette boîte sur votre laptop, sur un serveur d’entreprise ou dans le cloud AWS, le contenu se comportera exactement de la même façon.
Docker vs machine virtuelle
Section intitulée « Docker vs machine virtuelle »Si vous connaissez les machines virtuelles (VM), vous vous demandez peut-être quelle est la différence. La réponse tient en un mot : légèreté.
Une machine virtuelle embarque un système d’exploitation complet. C’est comme si vous transportiez une maison entière pour chaque application. Un conteneur Docker, lui, partage le noyau Linux de la machine hôte — il ne transporte que le strict nécessaire.
| Critère | Machine virtuelle | Conteneur Docker |
|---|---|---|
| Démarrage | Minutes (boot complet de l’OS) | Secondes (processus isolé) |
| Taille | Gigaoctets (OS complet) | Mégaoctets (application seule) |
| Isolation | Complète (hyperviseur) | Processus (namespaces Linux) |
| Ressources | Allouées en bloc | Partagées dynamiquement |
| Densité | 10-20 VM par serveur | Centaines de conteneurs |
En pratique, vous pouvez lancer des dizaines de conteneurs sur un laptop ordinaire, là où vous seriez limité à quelques VM.
L’histoire de Docker en bref
Section intitulée « L’histoire de Docker en bref »L’histoire de Docker commence en 2010, lorsque Solomon Hykes, un ingénieur français, travaille sur un projet de virtualisation légère. L’idée : simplifier le déploiement d’applications en utilisant les conteneurs Linux (une technologie existante mais complexe à utiliser).
En 2013, Docker est publié en open source. La promesse est simple : « Build once, run anywhere » (construisez une fois, exécutez partout). En quelques années, Docker devient le standard de facto de la conteneurisation. Aujourd’hui, il est utilisé par des millions de développeurs et d’entreprises dans le monde.
Concepts fondamentaux
Section intitulée « Concepts fondamentaux »Avant de lancer votre premier conteneur, prenons quelques minutes pour comprendre les briques de base de Docker. Ces concepts reviendront constamment — les maîtriser maintenant vous fera gagner un temps précieux par la suite.
Images Docker
Section intitulée « Images Docker »Une image Docker est comme une recette de cuisine. Elle contient toutes les instructions et ingrédients pour préparer un plat (votre application), mais ce n’est pas le plat lui-même.
Plus techniquement, une image est un package immuable qui contient :
- Le code de votre application
- Les bibliothèques et dépendances nécessaires
- Les fichiers de configuration
- Les variables d’environnement
Une fois créée, une image ne change jamais. C’est cette immutabilité qui garantit la reproductibilité : la même image donnera toujours le même résultat, que vous la lanciez aujourd’hui ou dans six mois.
Les images sont souvent basées sur d’autres images. Par exemple, une image d’application Python sera basée sur une image Python officielle, elle-même basée sur une image Debian ou Alpine. C’est le principe des couches (layers).
Conteneurs
Section intitulée « Conteneurs »Un conteneur est une instance en cours d’exécution d’une image. Si l’image est la recette, le conteneur est le plat préparé et servi.
Contrairement à l’image (immuable), un conteneur a un état qui peut changer : des fichiers peuvent être créés, modifiés, supprimés pendant son exécution. Mais attention : ces modifications disparaissent quand le conteneur est supprimé (sauf si vous utilisez des volumes, on y vient).
Un conteneur fonctionne dans un environnement isolé grâce à deux mécanismes Linux :
- Les namespaces : isolent ce que le conteneur voit (processus, réseau, utilisateurs…)
- Les cgroups : limitent ce que le conteneur utilise (CPU, mémoire, I/O…)
Dockerfile
Section intitulée « Dockerfile »Le Dockerfile est un fichier texte qui contient les instructions pour construire une image Docker. C’est la recette écrite, étape par étape, que Docker exécute pour créer votre image.
Chaque ligne du Dockerfile correspond à une instruction :
FROM: l’image de base sur laquelle construireRUN: exécuter une commande (installer un paquet, créer un dossier…)COPY: copier des fichiers depuis votre machine vers l’imageENV: définir une variable d’environnementEXPOSE: documenter le port sur lequel l’application écouteCMD: la commande à exécuter au démarrage du conteneur
Nous verrons plus tard comment écrire un Dockerfile efficace.
Les couches (Layers)
Section intitulée « Les couches (Layers) »Chaque instruction du Dockerfile crée une couche dans l’image finale. Ces couches sont empilées les unes sur les autres et forment ensemble l’image complète.
L’intérêt de ce système de couches est l’optimisation :
- Cache : si une couche n’a pas changé, Docker la réutilise au lieu de la reconstruire
- Partage : plusieurs images basées sur la même image de base partagent les couches communes
- Téléchargement : seules les couches manquantes sont téléchargées
Par exemple, si vous avez 10 images basées sur python:3.12, la couche Python
n’est stockée qu’une seule fois sur votre disque.
Les volumes résolvent un problème fondamental : comment conserver des données alors que les conteneurs sont éphémères ?
Un volume est un espace de stockage en dehors du conteneur qui persiste même si le conteneur est supprimé. Les cas d’usage typiques :
- Base de données (MySQL, PostgreSQL) : les données doivent survivre aux redémarrages
- Fichiers uploadés par les utilisateurs
- Logs que vous voulez analyser plus tard
- Configuration que vous voulez modifier sans reconstruire l’image
Docker propose plusieurs types de montages :
| Type | Description | Cas d’usage |
|---|---|---|
| Volume nommé | Géré par Docker, stocké dans /var/lib/docker/volumes/ | Données de bases de données, fichiers applicatifs persistants |
| Bind mount | Pointe vers un chemin sur l’hôte | Développement (code source), fichiers de configuration |
| tmpfs | Stocké en mémoire uniquement | Données sensibles temporaires, cache éphémère |
Docker crée automatiquement des réseaux virtuels pour que vos conteneurs puissent communiquer entre eux et avec l’extérieur.
Par défaut, Docker utilise le réseau bridge qui isole les conteneurs tout en leur permettant de communiquer. Mais vous pouvez créer différents types de réseaux selon vos besoins :
| Type de réseau | Description | Quand l’utiliser |
|---|---|---|
| bridge | Réseau isolé par défaut | Applications multi-conteneurs sur une seule machine |
| host | Partage la pile réseau de l’hôte | Performance réseau maximale (pas d’isolation) |
| overlay | Communication entre hôtes différents | Clusters Docker Swarm ou Kubernetes |
| none | Pas de réseau | Conteneurs sans accès réseau (sécurité) |
Pour l’instant, retenez que Docker gère le réseau automatiquement — vous pouvez lancer des conteneurs sans vous soucier de la configuration réseau.
Disponibilité de Docker
Section intitulée « Disponibilité de Docker »Docker est disponible sur toutes les plateformes majeures :
Linux : Ubuntu, Debian, Fedora, RHEL, CentOS, Alpine, Arch Linux, openSUSE… Docker s’exécute nativement grâce au noyau Linux.
Windows : via Docker Desktop qui utilise WSL 2 (Windows Subsystem for Linux) pour exécuter Docker. Fonctionne sur Windows 10/11 Pro, Enterprise et Education.
macOS : via Docker Desktop ou Colima (alternative légère). Utilise une machine virtuelle Linux en arrière-plan car macOS n’a pas de noyau Linux.
Cloud : tous les grands providers (AWS, Google Cloud, Azure) proposent des services Docker pré-configurés.
Installation de Docker
Section intitulée « Installation de Docker »L’installation varie selon votre système d’exploitation. Je vous guide étape par étape pour chaque plateforme.
Installation sur Linux (Ubuntu/Debian)
Section intitulée « Installation sur Linux (Ubuntu/Debian) »L’installation sur Linux est la plus directe car Docker s’exécute nativement sur le noyau Linux.
-
Mettre à jour le système
Commencez par mettre à jour la liste des paquets. Cette étape garantit que vous installerez les versions les plus récentes des dépendances.
Fenêtre de terminal sudo apt-get updatesudo apt-get upgrade -y -
Installer les prérequis
Docker nécessite quelques paquets pour télécharger de manière sécurisée depuis les dépôts HTTPS.
Fenêtre de terminal sudo apt-get install -y \apt-transport-https \ca-certificates \curl \software-properties-common -
Ajouter la clé GPG officielle
Cette clé permet de vérifier que les paquets téléchargés proviennent bien de Docker et n’ont pas été altérés.
Fenêtre de terminal curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg -
Ajouter le dépôt Docker
Configurez APT pour utiliser le dépôt officiel Docker. La commande détecte automatiquement votre architecture (amd64, arm64) et votre version d’Ubuntu.
Fenêtre de terminal echo "deb [arch=$(dpkg --print-architecture) \signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] \https://download.docker.com/linux/ubuntu \$(lsb_release -cs) stable" | \sudo tee /etc/apt/sources.list.d/docker.list > /dev/null -
Installer Docker Engine
Mettez à jour la liste des paquets (pour inclure le nouveau dépôt) puis installez Docker.
Fenêtre de terminal sudo apt-get updatesudo apt-get install -y docker-ce docker-ce-cli containerd.ioVérification : Docker devrait maintenant être installé. Vérifiez avec :
Fenêtre de terminal docker --version# Docker version 27.x.x, build xxxxxxx -
Configurer les permissions utilisateur
Par défaut, Docker nécessite les droits root (sudo). Pour éviter de taper
sudoà chaque commande, ajoutez votre utilisateur au groupedocker:Fenêtre de terminal sudo usermod -aG docker ${USER}Important : déconnectez-vous puis reconnectez-vous pour que le changement prenne effet. Vous pouvez aussi lancer
newgrp dockerpour l’appliquer immédiatement dans le terminal courant.
Installation sur Windows
Section intitulée « Installation sur Windows »Sur Windows, Docker s’installe via Docker Desktop, une application qui fournit une interface graphique et la CLI Docker.
-
Télécharger Docker Desktop
Rendez-vous sur docker.com/products/docker-desktop et téléchargez l’installateur Windows.
-
Lancer l’installation
Double-cliquez sur le fichier téléchargé et suivez l’assistant. Lors de l’installation :
- Cochez « Use WSL 2 instead of Hyper-V » (recommandé pour les performances)
- Acceptez les paramètres par défaut
-
Redémarrer si demandé
Windows peut nécessiter un redémarrage pour finaliser l’activation de WSL 2.
-
Lancer Docker Desktop
Après le redémarrage, lancez Docker Desktop depuis le menu Démarrer. Une icône apparaît dans la barre des tâches :
- Icône verte : Docker est prêt
- Icône orange : Docker démarre
- Icône rouge : problème de configuration
-
Vérifier l’installation
Ouvrez PowerShell ou le terminal Windows et tapez :
Fenêtre de terminal docker --versiondocker run hello-world
Installation sur macOS avec Colima
Section intitulée « Installation sur macOS avec Colima »Colima est une alternative légère à Docker Desktop sur macOS. Il utilise une machine virtuelle Lima et consomme moins de ressources système.
-
Installer Homebrew (si pas déjà fait)
Homebrew est le gestionnaire de paquets standard sur macOS :
Fenêtre de terminal /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" -
Installer Docker CLI et Colima
Fenêtre de terminal brew install docker colima -
Démarrer Colima
Lancez Colima avec la configuration par défaut (2 CPU, 2 Go RAM) :
Fenêtre de terminal colima startPour plus de ressources (recommandé pour des projets conséquents) :
Fenêtre de terminal colima start --cpu 4 --memory 8 --disk 100 -
Vérifier l’installation
Fenêtre de terminal docker --versiondocker run hello-world -
Gérer Colima
Quelques commandes utiles pour gérer la VM Colima :
Fenêtre de terminal colima status # État de la VMcolima stop # Arrêter Docker (et la VM)colima start # Redémarrercolima delete # Supprimer la VM (recrée une fresh)
Vérification du bon fonctionnement
Section intitulée « Vérification du bon fonctionnement »Quelle que soit la méthode d’installation, vérifiez que Docker fonctionne correctement avec le conteneur de test hello-world :
docker run hello-worldSi tout est bien configuré, vous verrez un message de bienvenue expliquant ce qui vient de se passer :
- Docker a téléchargé l’image
hello-worlddepuis Docker Hub - Un conteneur a été créé à partir de cette image
- Le conteneur a affiché le message puis s’est arrêté
Si vous obtenez une erreur « permission denied » : vérifiez que vous avez bien ajouté votre utilisateur au groupe docker (Linux) ou que Docker Desktop est bien démarré (Windows/macOS).
Votre premier conteneur
Section intitulée « Votre premier conteneur »Maintenant que Docker est installé, lançons quelques conteneurs pour comprendre les commandes de base.
Lancer un conteneur simple
Section intitulée « Lancer un conteneur simple »La commande docker run est la plus utilisée. Elle crée et démarre un
conteneur à partir d’une image.
Lancez un conteneur Ubuntu interactif :
docker run -it ubuntu bashQue se passe-t-il ?
- Docker vérifie si l’image
ubuntuexiste localement - Si non, il la télécharge depuis Docker Hub
- Il crée un conteneur à partir de cette image
- Il lance
bashà l’intérieur et vous connecte au terminal
Vous êtes maintenant à l’intérieur du conteneur. Le prompt a changé
(root@<container_id>:#). Essayez quelques commandes :
cat /etc/os-release # Vérifie que c'est bien Ubuntuls / # Liste les fichiers à la racineexit # Quitte le conteneur (et l'arrête)Lancer un serveur web
Section intitulée « Lancer un serveur web »Lançons maintenant quelque chose de plus utile — un serveur web Nginx :
docker run -d -p 8080:80 --name mon-nginx nginxDécortiquons cette commande :
| Option | Signification |
|---|---|
-d | Detached : le conteneur s’exécute en arrière-plan |
-p 8080:80 | Port mapping : le port 8080 de votre machine → port 80 du conteneur |
--name mon-nginx | Donne un nom explicite au conteneur (sinon Docker génère un nom aléatoire) |
nginx | L’image à utiliser |
Vérification : ouvrez votre navigateur à l’adresse http://localhost:8080.
Vous devriez voir la page d’accueil de Nginx.
Pour voir les conteneurs en cours d’exécution :
docker psRésultat :
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMESa1b2c3d4e5f6 nginx "/docker-entrypoint.…" 2 minutes ago Up 2 minutes 0.0.0.0:8080->80/tcp mon-nginxLes options essentielles de docker run
Section intitulée « Les options essentielles de docker run »La commande docker run accepte de nombreuses options. Voici les plus utilisées
au quotidien :
| Option | Description | Exemple |
|---|---|---|
-d | Mode détaché (arrière-plan) | docker run -d nginx |
-p host:container | Mapping de port | docker run -p 8080:80 nginx |
--name | Nom du conteneur | docker run --name web nginx |
-e VAR=val | Variable d’environnement | docker run -e DEBUG=true myapp |
-v host:container | Monter un volume | docker run -v ./data:/app/data nginx |
--rm | Supprimer après arrêt | docker run --rm ubuntu echo "test" |
-it | Mode interactif + terminal | docker run -it ubuntu bash |
--restart | Politique de redémarrage | docker run --restart=always nginx |
Un exemple combinant plusieurs options :
docker run -d \ --name mon-app \ -p 3000:3000 \ -e NODE_ENV=production \ -v $(pwd)/logs:/app/logs \ --restart unless-stopped \ node:20-alpine node server.jsCette commande lance une application Node.js en production avec persistance des logs et redémarrage automatique.
Gérer les images Docker
Section intitulée « Gérer les images Docker »Les images sont les briques de base de Docker. Apprenons à les rechercher, télécharger, lister et supprimer.
Rechercher une image
Section intitulée « Rechercher une image »Docker Hub est le registre public où les éditeurs et la communauté publient leurs images. Vous pouvez rechercher directement depuis le terminal :
docker search pythonRésultat :
NAME DESCRIPTION STARS OFFICIALpython Python is an interpreted, interactive... 9500 [OK]pypy PyPy is a fast, compliant alternative... 400 [OK]bitnami/python Bitnami Python Docker Image 30Conseil : privilégiez les images [OFFICIAL] — elles sont maintenues par les éditeurs officiels et régulièrement mises à jour avec les correctifs de sécurité.
Télécharger une image (pull)
Section intitulée « Télécharger une image (pull) »Pour télécharger une image sans lancer de conteneur :
docker pull nginxDocker télécharge l’image couche par couche :
Using default tag: latestlatest: Pulling from library/nginxa2abf6c4d29d: Pull completea9edb18cadd1: Pull complete589b7251471a: Pull complete...Digest: sha256:abc123...Status: Downloaded newer image for nginx:latestLes tags : par défaut, Docker utilise le tag latest. Mais vous pouvez (et
devriez) spécifier une version précise :
docker pull nginx:1.25-alpine # Version 1.25 basée sur Alpine (légère)docker pull python:3.12-slim # Python 3.12, image minimaledocker pull node:20-bookworm # Node.js 20 sur Debian BookwormLister les images locales
Section intitulée « Lister les images locales »Pour voir toutes les images présentes sur votre machine :
docker imagesRésultat :
REPOSITORY TAG IMAGE ID CREATED SIZEnginx latest 605c77e624dd 2 weeks ago 187MBnginx 1.25-alpine a6eb2a334a9f 2 weeks ago 43MBpython 3.12-slim c1e47f78a7d4 3 days ago 156MBubuntu latest ca2b0f26964c 4 weeks ago 77MBLes colonnes importantes :
- REPOSITORY : nom de l’image
- TAG : version/variante de l’image
- IMAGE ID : identifiant unique (utile pour les commandes)
- SIZE : espace disque occupé
Pour avoir plus de détails sur une image spécifique :
docker inspect nginxCette commande retourne un JSON complet avec la configuration, les couches, les variables d’environnement, les ports exposés, etc.
Supprimer des images
Section intitulée « Supprimer des images »Pour libérer de l’espace disque, supprimez les images dont vous n’avez plus besoin :
# Supprimer une image par son nomdocker rmi nginx:1.25-alpine
# Supprimer par IDdocker rmi a6eb2a334a9f
# Supprimer plusieurs imagesdocker rmi nginx python ubuntuSi une image est utilisée par un conteneur (même arrêté), Docker refusera de la supprimer. Deux solutions :
# Option 1 : supprimer d'abord le conteneurdocker rm mon-conteneurdocker rmi nginx
# Option 2 : forcer la suppressiondocker rmi -f nginxPour nettoyer toutes les images non utilisées d’un coup :
docker image prune # Images « dangling » (sans tag)docker image prune -a # Toutes les images non utiliséesGérer les conteneurs
Section intitulée « Gérer les conteneurs »Un conteneur passe par différents états durant son cycle de vie : créé, en cours d’exécution, arrêté, supprimé. Voyons comment gérer ces états.
Lister les conteneurs
Section intitulée « Lister les conteneurs »# Conteneurs en cours d'exécutiondocker ps
# Tous les conteneurs (y compris arrêtés)docker ps -aExemple de sortie :
CONTAINER ID IMAGE COMMAND STATUS NAMESa1b2c3d4e5f6 nginx "/docker-entrypoint.…" Up 2 hours mon-nginxb2c3d4e5f6a7 ubuntu "bash" Exited (0) 10 minutes ago hopeful_curieLes statuts possibles :
| Status | Signification |
|---|---|
Created | Conteneur créé mais jamais démarré |
Up X minutes | En cours d’exécution depuis X minutes |
Exited (0) | Arrêté normalement (code retour 0) |
Exited (1) | Arrêté avec erreur (code retour non nul) |
Paused | Suspendu (processus gelés) |
Démarrer, arrêter, redémarrer
Section intitulée « Démarrer, arrêter, redémarrer »# Arrêter un conteneur (envoie SIGTERM, puis SIGKILL après 10s)docker stop mon-nginx
# Démarrer un conteneur arrêtédocker start mon-nginx
# Redémarrer (stop + start)docker restart mon-nginx
# Arrêt immédiat (SIGKILL, pas de graceful shutdown)docker kill mon-nginxSupprimer des conteneurs
Section intitulée « Supprimer des conteneurs »Un conteneur arrêté occupe toujours de l’espace disque. Pour le supprimer définitivement :
# Supprimer un conteneur arrêtédocker rm mon-nginx
# Supprimer plusieurs conteneursdocker rm container1 container2
# Forcer la suppression d'un conteneur actif (stop + rm)docker rm -f mon-nginx
# Supprimer tous les conteneurs arrêtésdocker container pruneConsulter les logs
Section intitulée « Consulter les logs »Les logs sont essentiels pour comprendre ce qui se passe dans un conteneur :
# Tous les logsdocker logs mon-nginx
# Suivre les logs en temps réel (comme tail -f)docker logs -f mon-nginx
# Les 50 dernières lignesdocker logs --tail 50 mon-nginx
# Avec timestampsdocker logs -t mon-nginxExécuter une commande dans un conteneur
Section intitulée « Exécuter une commande dans un conteneur »Pour lancer une commande dans un conteneur en cours d’exécution :
# Ouvrir un shell interactifdocker exec -it mon-nginx bash
# Exécuter une commande simpledocker exec mon-nginx nginx -t # Tester la config Nginx
# En tant qu'autre utilisateurdocker exec -u www-data mon-nginx whoamiC’est très utile pour le debugging : vous pouvez inspecter les fichiers, lancer des commandes, vérifier les processus sans arrêter le conteneur.
Construire une image Docker
Section intitulée « Construire une image Docker »Jusqu’ici, nous avons utilisé des images existantes. Mais la vraie puissance de Docker vient de la capacité à créer vos propres images avec vos applications.
Anatomie d’un Dockerfile
Section intitulée « Anatomie d’un Dockerfile »Un Dockerfile est un fichier texte qui décrit, étape par étape, comment construire une image. Voici un exemple commenté :
# Image de base : Python 3.12 sur Alpine Linux (légère)FROM python:3.12-alpine
# Métadonnées de l'imageLABEL maintainer="vous@example.com"LABEL description="Mon application Python"
# Définir le répertoire de travailWORKDIR /app
# Copier le fichier des dépendancesCOPY requirements.txt .
# Installer les dépendances PythonRUN pip install --no-cache-dir -r requirements.txt
# Copier le code sourceCOPY src/ ./src/
# Variable d'environnementENV FLASK_ENV=production
# Port exposé (documentation)EXPOSE 5000
# Commande par défaut au démarrageCMD ["python", "src/app.py"]Les instructions principales
Section intitulée « Les instructions principales »| Instruction | Description | Exemple |
|---|---|---|
FROM | Image de base (obligatoire, première instruction) | FROM python:3.12-alpine |
WORKDIR | Définit le répertoire de travail | WORKDIR /app |
COPY | Copie fichiers/dossiers depuis l’hôte | COPY . /app |
ADD | Comme COPY, mais peut extraire des archives | ADD app.tar.gz /app |
RUN | Exécute une commande (création de couche) | RUN apt-get install -y curl |
ENV | Définit une variable d’environnement | ENV NODE_ENV=production |
EXPOSE | Documente le port utilisé | EXPOSE 3000 |
CMD | Commande par défaut au démarrage | CMD ["node", "server.js"] |
ENTRYPOINT | Point d’entrée (non modifiable) | ENTRYPOINT ["nginx"] |
Construire l’image
Section intitulée « Construire l’image »Avec le Dockerfile prêt, construisez l’image avec docker build :
docker build -t mon-app:1.0 .Explication :
-t mon-app:1.0: tag l’image avec un nom et une version.: contexte de build (le répertoire contenant le Dockerfile)
Docker exécute chaque instruction et crée une couche :
[+] Building 15.2s (10/10) FINISHED => [1/6] FROM python:3.12-alpine => [2/6] WORKDIR /app => [3/6] COPY requirements.txt . => [4/6] RUN pip install --no-cache-dir -r requirements.txt => [5/6] COPY src/ ./src/ => [6/6] EXPOSE 5000 => exporting to image => naming to docker.io/library/mon-app:1.0Exemple complet : application Nginx personnalisée
Section intitulée « Exemple complet : application Nginx personnalisée »Créons une image Nginx avec une page HTML personnalisée :
FROM nginx:1.25-alpine
# Copier notre page HTMLCOPY index.html /usr/share/nginx/html/
# Copier une config personnalisée (optionnel)COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]Et le fichier index.html :
<!DOCTYPE html><html><head><title>Mon site Docker</title></head><body> <h1>Bienvenue sur mon conteneur Docker !</h1></body></html>Construction et test :
docker build -t mon-site:1.0 .docker run -d -p 8080:80 mon-site:1.0# Ouvrez http://localhost:8080Bonnes pratiques pour les Dockerfiles
Section intitulée « Bonnes pratiques pour les Dockerfiles »Quelques règles pour des images légères, sécurisées et rapides à construire :
1. Utilisez des images de base légères
# ✅ Préférez Alpine ou les variantes slimFROM python:3.12-alpineFROM node:20-slim
# ❌ Évitez les images complètes si pas nécessaireFROM ubuntu:22.042. Ordonnez les instructions par fréquence de changement
Les couches sont mises en cache. Si une couche change, toutes les suivantes sont reconstruites. Placez les fichiers qui changent souvent en dernier.
# ✅ Les dépendances changent moins souvent que le codeCOPY requirements.txt .RUN pip install -r requirements.txtCOPY src/ ./src/
# ❌ À chaque modif du code, pip install est relancéCOPY . /appRUN pip install -r requirements.txt3. Combinez les RUN pour réduire les couches
# ✅ Une seule coucheRUN apt-get update && \ apt-get install -y curl wget && \ rm -rf /var/lib/apt/lists/*
# ❌ Trois couches (et le cache apt reste)RUN apt-get updateRUN apt-get install -y curlRUN apt-get install -y wget4. Ne lancez pas en root
# Créer un utilisateur non-rootRUN addgroup -S appgroup && adduser -S appuser -G appgroupUSER appuserGérer les versions d’images
Section intitulée « Gérer les versions d’images »Une fois votre image créée, vous pouvez lui ajouter des tags supplémentaires
avec docker tag :
# L'image actuelledocker images mon-app# REPOSITORY TAG IMAGE ID# mon-app 1.0 abc123def
# Ajouter le tag "latest"docker tag mon-app:1.0 mon-app:latest
# Tagger pour un registre distantdocker tag mon-app:1.0 registry.example.com/mon-app:1.0Gérer les ressources Docker
Section intitulée « Gérer les ressources Docker »Docker accumule des ressources (images, conteneurs, volumes, réseaux) qui
peuvent occuper beaucoup d’espace disque. La commande docker system permet
de gérer tout ça.
Voir l’utilisation disque
Section intitulée « Voir l’utilisation disque »docker system dfRésultat :
TYPE TOTAL ACTIVE SIZE RECLAIMABLEImages 12 4 3.2GB 1.8GB (56%)Containers 8 2 150MB 100MB (66%)Local Volumes 5 3 500MB 200MB (40%)Build Cache 0 0 0B 0BCela vous montre exactement ce qui consomme de l’espace et ce qui peut être nettoyé.
Nettoyer les ressources inutilisées
Section intitulée « Nettoyer les ressources inutilisées »La commande docker system prune est votre meilleure amie pour faire le
ménage :
# Nettoyage de base (conteneurs arrêtés, images dangling, réseaux inutilisés)docker system prune
# Inclure les images non utilisées (même avec tags)docker system prune -a
# Inclure les volumes orphelins (attention aux données !)docker system prune --volumes
# Sans confirmation (pour scripts)docker system prune -afInformations système
Section intitulée « Informations système »Pour diagnostiquer des problèmes ou comprendre votre configuration Docker :
docker system infoCette commande affiche :
- Version de Docker
- Nombre de conteneurs/images
- Driver de stockage
- Configuration du réseau
- Ressources système (CPU, mémoire)
Surveiller les événements
Section intitulée « Surveiller les événements »Pour voir ce qui se passe en temps réel sur votre installation Docker :
docker system eventsChaque action (création, démarrage, arrêt de conteneur, pull d’image…) génère un événement. Très utile pour le debugging.
Dépannage
Section intitulée « Dépannage »Voici les problèmes les plus fréquents et leurs solutions.
Erreurs courantes
Section intitulée « Erreurs courantes »| Symptôme | Cause probable | Solution |
|---|---|---|
permission denied | Utilisateur pas dans le groupe docker | sudo usermod -aG docker $USER puis reconnexion |
Cannot connect to Docker daemon | Docker pas démarré | sudo systemctl start docker (Linux) ou démarrer Docker Desktop |
port is already allocated | Port déjà utilisé | Choisir un autre port : -p 8081:80 |
no space left on device | Disque plein | docker system prune -a |
image not found | Mauvais nom d’image ou pas téléchargée | Vérifier le nom, docker pull |
OCI runtime create failed | Problème de permissions ou ressources | Vérifier les droits, mémoire disponible |
Le conteneur s’arrête immédiatement
Section intitulée « Le conteneur s’arrête immédiatement »Si un conteneur démarre puis s’arrête aussitôt :
# Voir le code de sortiedocker ps -a --filter "name=mon-conteneur"
# Consulter les logsdocker logs mon-conteneurCauses fréquentes :
- La commande principale a échoué (erreur dans l’application)
- Pas de processus en foreground (tout se lance en background et le conteneur n’a plus rien à faire)
- Fichier de configuration manquant ou incorrect
Impossible de supprimer une image
Section intitulée « Impossible de supprimer une image »# Erreur : image used by containerdocker rmi nginx# Error: conflict: unable to remove repository reference "nginx"
# Solution : lister et supprimer les conteneurs qui l'utilisentdocker ps -a --filter ancestor=nginxdocker rm <container_id>docker rmi nginxLe build Docker est lent
Section intitulée « Le build Docker est lent »- Vérifiez le contexte : Docker envoie tout le répertoire courant au daemon.
Utilisez un
.dockerignorepour exclurenode_modules/,.git/, etc. - Optimisez l’ordre des instructions : mettez les fichiers qui changent souvent en dernier
- Utilisez BuildKit :
DOCKER_BUILDKIT=1 docker build
À retenir
Section intitulée « À retenir »Voici les points essentiels de ce guide Docker :
-
Docker conteneurise vos applications avec tout leur environnement, garantissant un comportement identique partout
-
Image vs Conteneur : l’image est le template immuable, le conteneur est l’instance en exécution
-
Commandes essentielles :
docker runpour lancer un conteneurdocker pspour voir les conteneurs actifsdocker logspour consulter les logsdocker execpour exécuter des commandes dans un conteneurdocker buildpour créer une image depuis un Dockerfile
-
Bonnes pratiques Dockerfile : images légères (Alpine), ordre des instructions optimisé, pas de root, fichiers .dockerignore
-
Maintenance :
docker system prunerégulièrement pour libérer l’espace disque
Checklist de démarrage
Section intitulée « Checklist de démarrage »Avant de passer à la suite, vérifiez que vous savez :
- Installer Docker sur votre système
- Lancer un conteneur avec les options
-d,-p,--name - Consulter les logs d’un conteneur
- Lister et supprimer des conteneurs et images
- Écrire un Dockerfile simple
- Construire une image avec
docker build - Nettoyer les ressources inutilisées
Contrôle de connaissances
Section intitulée « Contrôle de connaissances »Contrôle de connaissances
Validez vos connaissances avec ce quiz interactif
Informations
- Le chronomètre démarre au clic sur Démarrer
- Questions à choix multiples, vrai/faux et réponses courtes
- Vous pouvez naviguer entre les questions
- Les résultats détaillés sont affichés à la fin
Lance le quiz et démarre le chronomètre
📋 Récapitulatif de vos réponses
Vérifiez vos réponses avant de soumettre. Cliquez sur une question pour la modifier.
Détail des réponses
Prochaines étapes
Section intitulée « Prochaines étapes »Ressources
Section intitulée « Ressources »- Documentation officielle : docs.docker.com
- Docker Hub : hub.docker.com
- BuildKit : Guide BuildKit
FAQ — Questions Fréquemment Posées
Section intitulée « FAQ — Questions Fréquemment Posées »Docker est une plateforme de conteneurisation qui permet d'empaqueter, distribuer et exécuter des applications dans des environnements isolés appelés conteneurs.
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
Un moteur de conteneurs (container engine) est le logiciel responsable de la création, du démarrage et de la gestion des conteneurs.
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
Voici un comparatif des principaux moteurs de conteneurs selon leurs particularités :
| 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
Voici les bonnes pratiques essentielles pour une configuration Docker robuste 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
La sécurisation Docker repose sur le principe du moindre privilège et des couches de défense en profondeur.
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
Docker propose trois types de stockage pour persister les données au-delà de la vie d'un conteneur.
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
Une image Docker est un modèle immuable qui contient tout le nécessaire pour exécuter une application, tandis qu'un conteneur est une instance en cours d'exécution de cette image.
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.
Docker propose plusieurs modes réseau pour connecter les conteneurs entre eux ou au monde extérieur.
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).
Docker Compose permet de définir et gérer des applications multi-conteneurs à l'aide d'un seul fichier YAML déclaratif.
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"
Docker et Kubernetes sont complémentaires : Docker conteneurise les applications, Kubernetes les orchestre à grande échelle.
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 automatique
apiVersion: 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) |
Un Dockerfile est un fichier texte contenant les instructions pour construire une image Docker de manière reproductible.
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