Aller au contenu principal

Docker et les containers : parce qu'il faut expliquer avec des pancakes.

Comprendre Docker et les conteneurs grâce à une analogie simple avec des pancakes. Apprenez les concepts d'image, conteneur, volume et réseau.

MAJ 11 min de lecture Ressorti
Sommaire · 16

Docker et les conteneurs, pour beaucoup, ça reste une abstraction opaque. Je m'en sers tous les jours. Et comme l'abstraction se digère mal à jeun, on va en parler avec des pancakes. À la fin, tu sauras ce qu'est une image, un conteneur, un volume, un réseau, et pourquoi une seule commande remplace une demi-journée à configurer des environnements.

Sans Docker : cauchemar en cuisine

Imagine un restaurant. Un vrai. Avec des clients pénibles qui veulent TOUS un pancake différent :

  • Jean-Michel veut des pancakes aux myrtilles.
  • Sophie veut des pancakes au chocolat.
  • Cyril veut un kebab.

Sauf qu'il y a un problème : tu n'as qu'une seule cuisine, une seule poêle, une seule table pour tout préparer. Résultat : les ingrédients se mélangent, les pancakes ont tous le même goût, et il y a des morceaux de kebab dans les myrtilles. Sympa.

En informatique, c'est pareil. Sans Docker, toutes tes applications tournent sur le même serveur, partagent les mêmes bibliothèques, les mêmes dépendances. Il suffit d'une mise à jour de trop, et une appli en casse une autre sans que tu comprennes pourquoi.

Docker : chacun sa mini-cuisine

Docker, c'est le pote débrouillard qui débarque et propose : « et si chaque pancake avait sa propre mini-cuisine ? »

Maintenant, chaque type de pancake a son espace de cuisson, ses ingrédients, sa poêle :

  • Isolation totale : les pancakes ne se mélangent plus, chacun garde son goût.
  • Zéro conflit : pas de gluten qui traîne dans le vegan, pas de chocolat dans la myrtille.
  • Nettoyage facile : un pancake est raté ? On le jette, on recommence, la cuisine reste propre.

En clair, Docker emballe chaque application avec tout ce dont elle a besoin : son runtime, ses dépendances, son environnement, dans un conteneur hermétique.

Images et conteneurs : la recette et le pancake

Docker fonctionne avec des images, qui sont des recettes toutes prêtes :

  • Une image Docker, c'est une recette de pancakes (« pancake au chocolat 1.0 »).
  • Un conteneur, c'est un pancake en train de cuire sur la poêle.

Tu veux refaire un pancake identique ? Pas besoin de tout recommencer à la main. Tu relances un conteneur depuis l'image, et tu obtiens le même pancake, au gramme près. L'image, c'est la recette ; le conteneur, c'est le pancake qui cuit.

Exemple de Dockerfile

Dockerfile
# On part d'une image avec PHP préinstallé
FROM php:8.4-cli

# On installe les extensions PHP pour parler à une base de données
RUN docker-php-ext-install pdo pdo_mysql

# On copie le code source dans le conteneur, dossier /app
COPY . /app

# On définit le dossier de travail par défaut
WORKDIR /app

# La commande lancée au démarrage du conteneur
CMD ["php", "index.php"]

Ligne par ligne :

  • FROM php:8.4-cli : on part d'une image officielle PHP en ligne de commande.
  • RUN docker-php-ext-install pdo pdo_mysql : on ajoute les extensions pour MySQL.
  • COPY . /app : on copie tout le projet local vers /app dans le conteneur.
  • WORKDIR /app : /app devient le dossier de travail des commandes suivantes.
  • CMD ["php", "index.php"] : la commande par défaut au démarrage (ici, lancer php index.php).

Docker Compose : parce qu'un seul pancake, c'est triste

Un pancake, c'est bien. Un petit-déj complet, c'est mieux :

  • Pancakes
  • Café
  • Sirop d'érable
  • Serveur web (parce qu'on bosse un peu quand même)

Plutôt que de tout démarrer à la main, Docker Compose s'en charge d'un coup. Dans un fichier compose.yaml, tu décris tous tes conteneurs et la façon dont ils se parlent. Une commande, et ton petit-déj est prêt.

Sur le même sujet

Petite note d'époque : la commande, aujourd'hui, c'est docker compose (deux mots, intégré à Docker), et non plus l'ancien docker-compose avec un tiret. Et le fichier s'appelle compose.yaml, la clé version: en tête n'a plus lieu d'être.

Exemple de compose.yaml

YAML
services:
  web:
    image: nginx:latest # Nginx comme serveur web
    ports:
      - "8080:80" # port 8080 de la machine vers le port 80 du conteneur
    volumes:
      - ./public:/usr/share/nginx/html # dossier public/ local servi par Nginx
  php:
    build: . # construit l'image depuis le Dockerfile ci-dessus
    volumes:
      - .:/app # monte le code source local dans le conteneur
  db:
    image: mysql:latest # MySQL comme base de données
    environment:
      MYSQL_ROOT_PASSWORD: root # mot de passe root
      MYSQL_DATABASE: myapp # crée une base "myapp" au démarrage

Ligne par ligne :

  • services: : la liste des conteneurs que Compose va gérer.
  • web: : le service Nginx.
  • image: nginx:latest : l'image officielle Nginx.
  • ports: - "8080:80" : redirige le port 8080 de la machine vers le 80 du conteneur.
  • volumes: - ./public:/usr/share/nginx/html : monte le dossier local pour servir son contenu.
  • php: : le service PHP, construit depuis le Dockerfile (build: .).
  • db: : le service MySQL, avec ses variables d'environnement.

Et un aveu sur ces exemples : nginx:latest et mysql:latest, tous les tutos s'en servent, celui-ci aussi. En vrai, latest change sous tes pieds à chaque pull : le petit-déj qui marchait hier casse demain sans que tu aies touché à rien. Sur un vrai projet, fige tes versions (nginx:1.27, mysql:8.4) : la recette exacte plutôt que « la recette du moment ».

Un mot honnête : ce blog ne tourne pas sur Nginx + PHP-FPM comme dans l'exemple. Il tourne sur FrankenPHP, un seul binaire au lieu de deux services. Mais le principe Compose est identique, et pour apprendre, ce trio web + php + db reste le plus parlant.

Pour aller plus loin

Pour aller plus loin

Les volumes : ne pas perdre sa garniture

C'est bien beau de faire des pancakes, mais si tu jettes toute la garniture chaque fois que tu changes de poêle, ça devient vite pénible.

Un volume Docker, c'est le tupperware posé à côté de ta cuisine temporaire :

  • Tu détruis ton conteneur ? Tes données précieuses survivent.
  • Tu veux réutiliser ces données dans un nouveau conteneur ? Aucun souci.
YAML
services:
  db:
    image: mysql:8.4
    volumes:
      - ./mes_donnees:/data/application # bind mount : un dossier local
      - ma_base_mysql:/var/lib/mysql    # volume nommé, géré par Docker

volumes:
  ma_base_mysql: # déclaré à la racine du fichier, Docker gère le stockage

Deux styles ici :

  • Le premier monte un dossier local dans le conteneur (pratique en dev, tu vois tes fichiers).
  • Le second crée un espace de stockage géré par Docker (idéal en prod).

Petit piège au passage : le volume nommé se déclare deux fois. Une fois dans le service qui s'en sert, une fois dans le bloc volumes: à la racine du fichier. Oublie le second et Compose te le fera savoir.

C'est la différence entre ramener ta propre garniture et utiliser celle du restaurant.

Les réseaux : la table commune des pancakes

Tes conteneurs ont besoin de se parler. Ton PHP doit joindre ta base de données, ton serveur web doit joindre ton PHP. Tout un écosystème de pancakes qui s'échangent des ingrédients.

Par défaut, Docker Compose crée un réseau où tous tes services se voient automatiquement. Chaque service est joignable par son nom :

YAML
# Dans ton compose.yaml
services:
  php:
    # ...
  db:
    # ...

# PHP joint la base avec "db" comme nom d'hôte.
# En PHP : $db = new PDO('mysql:host=db;dbname=myapp');

Tu peux aussi créer des réseaux dédiés pour cloisonner certains conteneurs :

YAML
networks:
  frontend:  # réseau pour l'interface web
  backend:   # réseau pour les services internes

Les variables d'environnement : l'assaisonnement des pancakes

Comme un chef qui ajuste le sel selon le service, tes applications s'adaptent à leur environnement :

YAML
environment:
  - APP_ENV=production
  - DATABASE_URL=mysql://user:pass@db:3306/app

Ou avec un fichier .env, pour garder tes mots de passe hors du fichier Compose :

YAML
env_file:
  - .env.production

C'est ta recette d'assaisonnement rangée à part, que tu changes sans toucher à la cuisine.

Docker Hub : le livre de recettes collaboratif

Pourquoi réinventer une recette de pancake quand des milliers de gens ont déjà partagé la leur ? Docker Hub, c'est un peu le GitHub des images Docker :

Terminal
docker pull mysql:8.0
docker pull php:8.4-fpm-alpine
docker pull nginx:alpine

Tu peux aussi y publier tes propres images :

Terminal
docker build -t mon-username/mon-image:latest .
docker push mon-username/mon-image:latest

Là, n'importe qui peut réutiliser ta recette de pancake au chocolat fondant.

Dockerfile multi-stage : la préparation pro

En cuisine pro, on prépare d'abord tous les ingrédients, puis on assemble. En Docker, c'est le build multi-étapes :

Dockerfile
# Étape de build : la cuisine où on prépare tout
FROM node:20 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

# Étape de production : juste ce qu'il faut pour servir
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html

Résultat : une image finale minuscule, avec seulement ce que tu sers. Pas d'outils de compilation, pas de déchets, juste un pancake prêt à passer à table.

Les commandes essentielles : le vocabulaire du chef pancake

Pour t'en sortir au quotidien, ce petit lot suffit :

Terminal
# Construire une image
docker build -t mon-image:v1 .

# Lancer un conteneur depuis une image
docker run -p 8080:80 mon-image:v1

# Voir les conteneurs en cours
docker ps

# Arrêter un conteneur
docker stop mon-conteneur

# Supprimer un conteneur
docker rm mon-conteneur

# Voir les logs d'un conteneur
docker logs mon-conteneur

# Ouvrir un shell dans un conteneur
docker exec -it mon-conteneur bash

Avec Compose, c'est encore plus court :

Terminal
# Démarrer tous les services
docker compose up -d

# Voir les logs de tous les services
docker compose logs

# Tout arrêter
docker compose down

La sécurité : parce que les pancakes empoisonnés, c'est pas cool

Ne fais pas tourner tes conteneurs en tant que root. C'est comme laisser les clés de ta cuisine à un inconnu :

Dockerfile
# Créer un utilisateur dédié, aux droits limités
RUN adduser --disabled-password --gecos "" pancakeuser
USER pancakeuser

Et surveille les permissions sur les volumes :

YAML
volumes:
  - ./config:/app/config:ro  # ro = lecture seule

Ces deux réflexes sont un début, pas une forteresse. Fermer la porte setuid, retirer les capabilities dont un service n'a pas besoin, c'est un cran plus loin, et j'y reviendrai dans un billet dédié.

Pourquoi Docker, au fond

Parce que sans Docker, c'est souvent ça :

  • « Ça marche sur ma machine », mais pas sur celle du collègue.
  • Des heures perdues à configurer des environnements.
  • Des conflits de dépendances qui donnent envie de tout casser.
  • Des déploiements manuels qui te font suer à 2 h du matin.

Avec Docker, c'est plutôt ça :

  • Chaque application est isolée, plus de dépendances qui se marchent dessus.
  • Un déploiement reproductible, la même image en dev et en prod.
  • Fini le « chez moi ça marchait ».
  • Une montée en charge plus simple le jour où ton site décolle.

Passer à la grande échelle : l'orchestration

Quand ton restaurant de pancakes devient une chaîne, tu veux un système qui pilote des milliers de mini-cuisines tout seul. C'est le rôle de :

  • Kubernetes : il gère des clusters entiers de conteneurs, répartit la charge, relance ce qui tombe, ajuste la taille selon le trafic.
  • Docker Swarm : la version simplifiée, intégrée à Docker.

Est-ce qu'il te le faut ? Pour une chaîne mondiale, oui. Pour un blog sur un VPS, la réponse est plus nuancée, et honnêtement souvent non. C'est un débat à part entière, un autre pancake, sur lequel j'ai des choses à dire (bientôt).

On récapitule ? Non, on ouvre

Docker, c'est donner à chaque application sa propre mini-cuisine : ses ingrédients, ses ustensiles, sa recette. Moins de conflits, moins de « chez moi ça marchait », moins de galères de déploiement.

Ce billet s'arrête à la poêle : les images, les conteneurs, les volumes, les réseaux, Compose. Il ne descend pas dans le kernel ni ne monte jusqu'au cluster, ce sont d'autres étages.

Une fois tes mini-cuisines qui tournent, deux questions arrivent vite. La première : est-ce qu'il me faut vraiment Kubernetes pour orchestrer tout ça ? La seconde : est-ce que mes conteneurs sont bien fermés à clé, ou est-ce qu'un sudo traîne dans la cuisine ? Deux pancakes pour un prochain petit-déj.

Et toi, c'est quoi le premier truc que tu vas conteneuriser ?

Une coquille, une erreur dans ce billet ? Signale-la-moi.

Ce billet est publié sous licence Creative Commons BY-NC-SA 4.0 (attribution, pas d'usage commercial, partage dans les mêmes conditions).

Vous aimerez aussi

Activez uniquement ce que vous souhaitez. Vos choix sont conservés 6 mois.

Strictement nécessaires

Indispensables au fonctionnement du site (session, sécurité, préférence d'affichage). Aucune donnée n'est partagée à des tiers et aucun consentement n'est requis.

Toujours actif

Mesure d'audience

Statistiques via Google Analytics (GA4) : pages vues, source du trafic, navigateur et interactions clés. Dépose des cookies de mesure, activés seulement avec votre accord (Consent Mode). Sans publicité ciblée, sans Google Signals, sans partage commercial.

Contenus externes

Affiche les GIF animés hébergés par Giphy (CDN aux États-Unis). À l'affichage d'un GIF, votre adresse IP et votre navigateur sont transmis à Giphy. Sans votre accord, les GIF ne s'affichent pas.