Compilations multi-étapes et optimisation
Réduisez la taille des images et séparez la compilation de l’exécution.
Compilations multi-étapes et optimisation est une leçon PHP Academy gratuite sur CoddyKit. Ceci est la leçon 2 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage PHP Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours PHP Academy comprend 4 leçons au total.
Pourquoi plusieurs étapes
Une image à une seule étape emporte Composer, les dépendances de construction, les en-têtes de développement et votre dossier tests/ en production. Les constructions à plusieurs étapes vous permettent de compiler et d’installer dans une étape constructeur volumineuse, puis de ne copier que les artefacts terminés dans une étape d’exécution légère.
Résultat : des images plus petites, une surface d’attaque réduite, des téléchargements plus rapides et aucun compilateur livré en production.
Étapes nommées
Chaque FROM ... AS name démarre une nouvelle étape. Les étapes suivantes peuvent copier des fichiers depuis les précédentes avec COPY --from=name. Seule l’étape finale devient votre image ; les étapes intermédiaires sont supprimées, mais restent mises en cache.
# Stage 1: dependencies
FROM composer:2 AS vendor
WORKDIR /app
COPY composer.json composer.lock ./
RUN composer install --no-dev --no-scripts --prefer-dist --ignore-platform-reqs
# Stage 2: runtime
FROM php:8.3-fpm-alpine AS runtime
WORKDIR /app
COPY --from=vendor /app/vendor ./vendor
COPY . .Séparer les dépendances de construction
La compilation des extensions nécessite autoconf, gcc et des en-têtes de développement — aucun de ces éléments ne doit se trouver dans l’environnement d’exécution. Utilisez l’installeur dans une étape de construction, puis copiez les fichiers .so compilés et le fichier conf.d ini correspondant dans une étape d’exécution propre.
FROM php:8.3-fpm-alpine AS ext-builder
ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/
RUN chmod +x /usr/local/bin/install-php-extensions && \
install-php-extensions redis igbinary opcache intl
FROM php:8.3-fpm-alpine AS runtime
# Copy compiled extensions + their enable configs
COPY --from=ext-builder /usr/local/lib/php/extensions/ /usr/local/lib/php/extensions/
COPY --from=ext-builder /usr/local/etc/php/conf.d/ /usr/local/etc/php/conf.d/Ordre de mise en cache des couches
Docker met les couches en cache de haut en bas et invalide tout ce qui se trouve sous une couche modifiée. Classez-les de la couche qui change le moins à celle qui change le plus souvent :
- Base et extensions (rarement)
composer.locket installation (occasionnellement)- Code source de l’application (à chaque validation)
- Génération du chargement automatique (à chaque validation)
Ainsi, une modification limitée au code réutilise entièrement la couche vendor mise en cache.
# BAD: copying all source before composer install
# busts the vendor layer on every code change
COPY . .
RUN composer install
# GOOD: lock first, then source
COPY composer.json composer.lock ./
RUN composer install --no-dev --no-autoloader
COPY . .
RUN composer dump-autoload --optimizeMontages de cache BuildKit
Avec BuildKit (DOCKER_BUILDKIT=1), vous pouvez monter un cache persistant qui survit aux constructions successives sans se retrouver dans l’image. C’est idéal pour le cache global de Composer, afin que les constructions répétées évitent de retélécharger les paquets.
# syntax=docker/dockerfile:1
FROM composer:2 AS vendor
WORKDIR /app
COPY composer.json composer.lock ./
RUN --mount=type=cache,target=/tmp/composer-cache \
COMPOSER_CACHE_DIR=/tmp/composer-cache \
composer install --no-dev --prefer-distMesurer la taille de l’image
Examinez la répartition des couches pour repérer les éléments superflus. docker history indique la taille ajoutée par chaque instruction ; des outils comme dive montrent l’espace gaspillé. L’objectif est d’obtenir une étape d’exécution sans compilateurs, sans Composer et sans dépendances de développement.
# Compare sizes
docker images myapp
# Per-layer contribution
docker history --no-trunc --format '{{.Size}}\t{{.CreatedBy}}' myapp:latest
# Deep inspection of wasted bytes
dive myapp:latestAlléger l’étape finale
L’étape d’exécution ne doit PAS contenir Composer, le script extension-installer ni votre suite de tests. Copiez vendor et le code source depuis les étapes de construction ; n’exécutez jamais composer dans l’étape finale. Supprimez l’installeur après utilisation si vous devez l’exécuter à cet endroit.
FROM php:8.3-fpm-alpine AS runtime
WORKDIR /app
# bring extensions + vendor in from builders — no Composer here
COPY --from=ext-builder /usr/local/lib/php/extensions/ /usr/local/lib/php/extensions/
COPY --from=ext-builder /usr/local/etc/php/conf.d/ /usr/local/etc/php/conf.d/
COPY --from=vendor /app/vendor ./vendor
COPY . .
USER www-data
CMD ["php-fpm"]Limites de Distroless / Scratch
PHP ne peut pas s’exécuter sur un scratch véritablement vide — il a besoin de libc et de bibliothèques partagées. Le minimum pratique est alpine (musl) ou une version minimale de Debian de type distroless. Alpine est la solution la plus petite, mais faites attention aux bibliothèques natives qui attendent glibc ; si vous rencontrez des erreurs de segmentation avec NSS/ICU, utilisez php:8.3-fpm-bookworm comme solution de repli.
# Smallest practical PHP runtime
FROM php:8.3-fpm-alpine
# If musl causes native-lib issues (e.g., some ICU edge cases),
# the glibc Debian slim variant is the safe fallback:
# FROM php:8.3-fpm-bookwormCibler les étapes
Un seul Dockerfile peut servir au développement et à la production grâce à --target. Ajoutez une étape dev au-dessus de l’étape d’exécution qui réinstalle les dépendances de développement de Composer et Xdebug ; construisez --target=runtime pour la production et --target=dev en local.
FROM runtime AS dev
ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/
RUN chmod +x /usr/local/bin/install-php-extensions && \
install-php-extensions xdebug @composer
USER root
RUN composer install # includes dev deps
# Build prod: docker build --target runtime -t app:prod .
# Build dev: docker build --target dev -t app:dev .Réfléchir à la taille des couches
Un modèle mental rapide vous aide à prévoir le comportement du cache. Cet extrait CLI simule l’erreur classique d’une croissance illimitée d’une couche par opposition à une croissance plafonnée, et montre pourquoi il est important d’intégrer le nettoyage au même RUN.
<?php
// Simulate layer sizes (MB) for two strategies
$installSteps = [120, 8, 8, 8];
// Separate RUN per step keeps temp files in layers
$separate = array_sum($installSteps);
// Single RUN with cleanup removes temp files before commit
$combined = max($installSteps); // peak, then cleaned
echo "Separate layers total: {$separate} MB\n";
echo "Combined+cleanup: {$combined} MB\n";
echo 'Saved: ' . ($separate - $combined) . " MB\n";
?>Combiner et nettoyer dans un seul RUN
Chaque RUN est une couche ; supprimer des fichiers dans une couche ultérieure ne réduit pas la taille de l’image, car les couches précédentes contiennent toujours les octets. Installez, utilisez et nettoyez au sein d’un seul RUN afin que les fichiers temporaires ne soient jamais intégrés à l’image.
RUN apk add --no-cache --virtual .build-deps $PHPIZE_DEPS && \
pecl install redis && \
docker-php-ext-enable redis && \
apk del .build-deps && \
rm -rf /tmp/pear /var/cache/apk/*Vérification rapide
Pourquoi les dépendances de construction doivent-elles être supprimées dans le même RUN que celui où elles ont été installées ?
Récapitulatif
Les constructions à plusieurs étapes empêchent les compilateurs et les dépendances de développement d’entrer en production. Vous avez appris à nommer les étapes et à copier les artefacts avec COPY --from, à ordonner les couches de la moins à la plus volatile pour optimiser la mise en cache, à utiliser les montages de cache BuildKit pour Composer, à mesurer la taille avec docker history/dive, à choisir délibérément entre alpine et glibc, à cibler les étapes de développement et de production et à combiner l’installation et le nettoyage dans un seul RUN.
Apprends PHP avec un tuteur IA — gratuit
Écris et exécute du vrai code dans ton navigateur, obtiens de l'aide instantanée d'un tuteur IA disponible 24h/24, et reprends là où tu t'es arrêté sur le web ou dans l'app.
- Cours
- 49
- Leçons
- 195
Questions Fréquemment Posées
La leçon « Compilations multi-étapes et optimisation » est-elle gratuite ?
Oui — le texte complet de « Compilations multi-étapes et optimisation » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours PHP Academy, passe à CoddyKit PRO. Le cours PHP Academy comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Compilations multi-étapes et optimisation » ?
Réduisez la taille des images et séparez la compilation de l’exécution. Tu pratiques PHP Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer PHP Academy ?
Aucune expérience préalable n'est requise. PHP Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 2 sur 4.
Combien de temps prend la leçon « Compilations multi-étapes et optimisation » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon PHP Academy ?
Oui. Chaque leçon PHP Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- Conteneuriser une application PHP
- Compilations multi-étapes et optimisation
- Docker Compose pour les environnements locaux
- CI/CD avec GitHub Actions