Aller au contenu principal

Docker : images, layers et isolation kernel expliqués.

Comprendre le multi-stage build, les healthchecks et l'isolation kernel via la métaphore des pancakes.

MAJ 5 min de lecture
Sommaire · 9

Docker est souvent mal compris. Est-ce de la virtualisation ? Non. Est-ce un chroot glorifié ? Presque, mais avec des super-pouvoirs comme les namespaces & cgroups.

Mais oublions l'informatique pure un instant. Pour comprendre Docker, il faut savoir cuisiner, et plus précisément, cuisiner des pancakes.

Le monde d'avant

Dans notre boutique de pancakes, il n'y a qu'une seule cuisine commune pour tout le monde, (l'OS Host).

  • Le client A (Symfony) veut des pancakes aux myrtilles (besoin de PHP 8.2).
  • Le client B (une vieille version de WordPress) veut des crêpes au sarrasin (besoin de PHP 7.4).
  • Le client C (une vieille version de Node.js) veut un kebab (besoin de Node 18).

La guerre est déclarée ! Pour cuire la crêpe B, vous devez désinstaller la poêle "PHP 8.2" et visser la poêle "PHP 7.4". Il reste des traces de myrtilles. Le kebab a un goût de sarrasin. Une fuite de mémoire (un cuisinier maladroit) ruine tous les plats.

La solution Docker ? Et si chaque plat était cuisiné dans sa propre mini-cuisine hermétique, blanche, stérile et équipée uniquement du nécessaire ?

L'image : la recette

L'image Docker, c'est la recette plastifiée : elle est immuable. Sur mon site, j'utilise une recette sophistiquée en plusieurs étapes (Multi-Stage Build). Regardons le fichier réel devops/frankenphp/Dockerfile :

Dockerfile
# 1. La Base Commune (La Farine)
FROM dunglas/frankenphp:1-php8.5 AS frankenphp_upstream

# 2. Les Ustensiles (Extensions PHP)
FROM frankenphp_upstream AS frankenphp_base
RUN apt-get update && apt-get install -y --no-install-recommends \
    libmagickwand-dev libwebp-dev ...

Ici, je prépare la pâte mère. Chaque instruction RUN ajoute une couche (layer) invisible. Si je change la farine (l'image de base), tout le monde est affecté. Mais si je change juste le décor (le code source), la pâte n'est pas refaite.

Une particularité de mon Dockerfile est l'utilisation massive de COPY --link :

Dockerfile
COPY --link devops/frankenphp/conf.d/10-app.ini $PHP_INI_DIR/app.conf.d/

Sans --link, Docker devrait revérifier tous les ingrédients précédents. Avec --link, il ajoute cet ingrédient indépendamment, comme une cerise posée à la toute fin car c'est instantané.

Le multi-stage : dev vs prod

Notre Dockerfile se sépare ensuite en deux univers parallèles :

Dockerfile
# Univers DEV : Cuisine Ouverte (On goûte, on modifie)
FROM frankenphp_base AS frankenphp_dev
RUN install-php-extensions xdebug
CMD [ "frankenphp", "run", "--config", "/etc/caddy/Caddyfile", "--watch" ]

# Univers PROD : Cuisine Fermée (Scellé pour le client)
FROM frankenphp_base AS frankenphp_prod
ENV APP_ENV=prod
COPY --link . ./
RUN composer install --no-dev --classmap-authoritative
  • En Dev (--watch) : Le pancake reste "cru" au centre. On peut rajouter des pépites de chocolat (modifier le code) pendant la cuisson.
  • En Prod : Le pancake est cuit, emballé sous vide (--classmap-authoritative). Il est immuable.

Le Containeur

Le Containeur, c'est le moment où on verse la pâte dans la poêle. C'est l'instanciation de l'Image. Techniquement, Docker prend les layers en lecture seule (la recette) et ajoute une fine couche en écriture (Copy-on-Write) par-dessus.

Si le pancake brûle, on ne gratte pas le noir. On le jette (docker rm) et on recommence une cuisson parfaite (docker run).

L'orchestration : docker compose

Un pancake tout seul, c'est triste. Un petit-déjeuner complet, c'est :

  • Le pancake (PHP, FrankenPHP)
  • Le sirop d'érable (PostgreSQL)
  • Le jus d'orange (Redis)
  • Le toasteur (Meilisearch)

Docker compose est votre serveur. Il dresse toute la table d'un coup. Analysons le compose.yaml :

YAML
services:
    php:
        depends_on:
            database:
                condition: service_healthy # "Attends que le sirop soit chaud !"

Le healthcheck : le chef goûte

YAML
    database:
        healthcheck:
            test: [ "CMD", "pg_isready", "-d", "${POSTGRES_DB:-app_dev}" ]
            interval: 10s

Docker ne se contente pas d'allumer le gaz (lancer le processus). Il goûte (pg_isready) toutes les 10 secondes. Tant que le sirop n'est pas à température, il n'autorise pas le service des pancakes. Fini les crashs au démarrage !

Les volumes : le tupperware magique

YAML
        volumes:
            - database_data:/var/lib/postgresql/data:rw

Rappelez-vous : si je jette mon pancake brûlé (conteneur), je perds tout ce qui est dedans. Pour la base de données, c'est inacceptable.

J'utilise donc un volume (database_data). C'est un tupperware indestructible posé sur une étagère hors de la cuisine isolée. Même si la cuisine explose, le tupperware reste intact.

Le mot de la fin

Docker n'est pas magique. C'est une exploitation brillante du Kernel Linux (namespaces = isolation, cgroups = quotas).

Mais gardez cette image : vos serveurs ne sont plus des animaux de compagnie qu'on soigne quand ils sont malades (Servers as Pets).

  • Un "Pet" a un nom (Gandalf, Zeus). S'il est malade, on passe la nuit à le soigner. Sa mort est une tragédie.

Vos conteneurs sont du bétail (Servers as Cattle).

  • Ils n'ont pas de nom, juste un ID.
  • S'ils sont malades, on ne les soigne pas. On les abat (pardon, on les stoppe) et on en déploie un nouveau immédiatement.

C'est la philosophie du pancake. S'il est râté, on le jette. Pourquoi ?

Parce qu'on a la recette parfaite (Dockerfile) pour en refaire un million d'autres identiques à la seconde près.

Bon appétit !

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.