Le pipeline CI passe de douze à quatre minutes : l'équipe a basculé sur php:8.3-alpine, supprimé les layers apt et réduit l'image de 680 Mo à 95 Mo. Le merge est fêté. Trois jours plus tard, l'extension GD ne charge plus une police TrueType — musl et bibliothèques manquantes — et le générateur de vignettes produit des PNG vides.
Les images légères accélèrent pull, deploy et cold start. Elles ne simplifient pas automatiquement votre application. Confondre « petit Dockerfile » et « stack comprise » mène à des images qui bootent vite mais échouent silencieusement sur un edge case de prod.
Taille, layers et ce qui coûte vraiment du temps
Docker envoie des layers incrémentaux. Une image « lourde » avec un bon cache local peut deployer plus vite qu'une « légère » qui invalide tout à chaque commit parce que COPY . . est placé trop haut.
| Levier | Gain typique | Risque |
|---|---|---|
| Base alpine/slim | −50 à 80 % taille | Incompatibilités libc, packages manquants |
| Multi-stage | Retire toolchain du runtime | Oublier une lib runtime (ssl, tzdata) |
| .dockerignore | Cache plus stable | Exclure un fichier requis au build |
| Combine RUN apt | Moins de layers | Images difficiles à patcher ligne à ligne |
Mesurez le temps pull + start sur votre registry et votre hébergeur — pas seulement docker images en local.
Une image légère mal testée externalise le coût vers le debug nocturne.
Multi-stage : séparer build et runtime
Pattern classique PHP/Node :
- Stage builder : composer install, npm run build, compilation extensions.
- Stage runtime : copie
vendor/,public/build/, binaires compilés uniquement.
Évitez de copier .git, tests, node_modules dev, ou documentation. Vérifiez que les extensions PHP runtime (pdo_mysql, intl, opcache) sont installées dans la finale, pas seulement dans builder.
Sur hébergement avec registry privé (Scaleway, GitLab, Harbor), des images finales compactes réduisent aussi la facture stockage et egress — surtout avec dix microservices.
Alpine, slim, distroless : choisir la libc
Alpine (musl) : très petit, packages via apk. Problèmes fréquents avec wkhtmltopdf, certaines extensions PECL, binaires liés à glibc.
Debian/Ubuntu slim (glibc) : un peu plus lourd, écosystème plus prévisible pour PHP et Python.
Distroless / scratch : minimal, souvent sans shell — excellent pour Go ou Java, plus exigeant pour PHP-FPM où le debug compte.
Test matrix minimale : démarrage container, health check, chemin métier critique (upload image, PDF, appel API TLS).
.dockerignore et dépendances cachées — dans le mauvais sens
Un .dockerignore trop agressif qui exclut composer.lock ou fichiers de config force un composer update implicite au build — image « légère », builds non reproductibles.
À l'inverse, inclure tout le repo sans ignore gonfle le contexte envoyé au daemon et casse le cache à chaque commit doc.
Listez explicitement ce qui entre dans le contexte : lockfiles, patches, extensions custom. Documentez les libs système requises dans le Dockerfile (commentaire + RUN apk add --no-cache ...).
Sécurité, CVE et images « latest »
FROM node:latest ou php:8-apache sans tag patché regonfle et obscurcit les mises à jour. Pinnez php:8.3.12-fpm-bookworm et automatisez rebuild sur CVE.
Scanner (Trivy, Grype) sur l'image finale — pas seulement sur le Dockerfile. Une base alpine minimaliste avec une openssl vulnérable reste un risque.
Le sommet : la légèreté qui masque l'incompréhension
Gagner du temps sur le pull ne vaut rien si vous perdez une heure à reconstruire mentalement ce que l'ancienne image Debian installait implicitement.
Décider et avancer sans angle mort
Documentez les libs runtime, adoptez multi-stage, pinnez les bases, testez smoke en CI. Comparez alpine vs slim sur votre stack, pas sur un benchmark générique.
Pour héberger registry, runners CI et VPS Docker en Europe, voir notre annuaire et comparateur. Les guides couvrent le cadrage conteneurs.
Checklist release : pull image vierge, run health, exécuter un scénario métier, scanner CVE — avant de célébrer les mégaoctets économisés.
Questions fréquentes
Alpine est-il toujours le bon choix pour une image légère ?
Non — testez musl vs glibc pour votre stack ; debian-slim ou distroless peuvent être plus stables.
Qu'est-ce qu'un build multi-stage apporte ?
Sépare compilation et runtime ; l'image finale n'embarque pas la toolchain.
Comment accélérer le pull sans réduire la sécurité ?
Cache layers, .dockerignore, tags pinés — la vitesse vient aussi du cache que de la taille.
Faut-il un shell dans l'image de production ?
Trade-off debug vs surface d'attaque ; choisissez selon votre capacité d'observabilité externe.
Une image légère se juge au deploy du vendredi soir — pas au docker images du lundi matin.