En bref : pour exploiter PHP en conteneurs, choisissez la variante adaptée de l'image officielle (fpm, apache ou cli), activez le php.ini de production, n'installez que les extensions nécessaires et fixez des limites de mémoire et de processus cohérentes entre elles. Les conteneurs sont immuables : une mise à jour de sécurité de PHP comme celle de PHP2Shell n'agit que lorsque l'image est reconstruite et que chaque conteneur est redémarré. Cette reconstruction doit donc faire partie, comme processus fixe, de toute exploitation de conteneurs.
Pourquoi PHP en conteneurs ?
Les conteneurs regroupent PHP, les extensions et la configuration dans une image qui tourne de la même façon sur chaque serveur. Pour les entreprises, cela signifie : moins de surprises entre le test et la production, une restauration plus rapide et des niveaux de version clairs. Pour la sécurité, cela signifie aussi une nouvelle obligation : personne n'installe automatiquement les mises à jour dans un conteneur.
Cette page traite de l'exploitation courante. La manière de corriger concrètement des conteneurs existants contre PHP2Shell figure sous Corriger PHP dans les conteneurs Docker.
Choisir la bonne variante d'image
| Variante | Contenu | Usage typique |
|---|---|---|
php:<version>-fpm |
PHP-FPM, nécessite un serveur web en amont | production avec Nginx, Caddy ou un ingress |
php:<version>-apache |
Apache avec mod_php, par défaut mpm_prefork | architectures simples, applications anciennes |
php:<version>-cli |
ligne de commande, seule variante à contenir aussi php-cgi | tâches cron, workers de file d'attente, étapes de build |
…-alpine |
basée sur Alpine Linux avec musl | petites images, adaptations nécessaires pour certaines extensions |
…-bookworm, …-trixie |
basées sur la version Debian indiquée | base fixe pour des builds reproductibles |
Pour les nouveaux projets, la variante fpm avec un conteneur de serveur web distinct est généralement recommandée. Avec mod_php, l'équipe PHP voit, en lien avec PHP2Shell, le risque le plus élevé ; qui utilise l'image apache exploite précisément ce mode.
Construire une image de production
Un exemple allégé pour une application avec accès MySQL :
FROM php:8.4-fpm-alpine
# Activer la configuration de production (vivement recommandé par la doc de l'image)
RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"
# Uniquement les extensions nécessaires
RUN docker-php-ext-install -j"$(nproc)" pdo_mysql
# Réglages personnalisés
COPY zz-sicherheit.ini "$PHP_INI_DIR/conf.d/"
# Le code appartient à root ; les workers FPM tournent en tant que www-data et ne peuvent que le lire
COPY . /var/www/html
Les scripts utilitaires de l'image prennent en charge la construction des extensions : docker-php-ext-configure pour les options, docker-php-ext-install pour construire, docker-php-ext-enable pour activer, par exemple après pecl install. Si le code source est décompressé avec docker-php-source, il devrait, selon la doc, être supprimé dans la même couche. Le fichier zz-sicherheit.ini pourrait ressembler à ceci :
expose_php = Off
display_errors = Off
log_errors = On
session.use_strict_mode = 1
session.cookie_httponly = 1
Deux autres principes rendent les images plus robustes. Premièrement, l'image livrée ne contient que ce qui est nécessaire à l'exécution ; compilateurs, caches de paquets et fichiers de test relèvent d'une étape de build distincte. Deuxièmement, l'utilisateur sous lequel PHP tourne ne doit pouvoir écrire que là où c'est nécessaire, par exemple dans les répertoires d'upload ou de cache sur des volumes montés. De nombreuses équipes exploitent en outre le conteneur avec un système de fichiers en lecture seule. Un fichier PHP introduit a alors nettement plus de mal à s'y maintenir durablement, et chaque redémarrage rétablit l'état propre de l'image. Cela ne remplace pas une investigation après un incident, mais réduit sensiblement la surface d'attaque.
Processus, mémoire et logs dans le conteneur
Trois leviers déterminent si un conteneur PHP tourne de façon stable.
- Nombre de workers :
pm.max_childrendans le pool FPM détermine combien de requêtes sont traitées simultanément. Chaque worker peut occuper jusqu'àmemory_limit. - Limite de mémoire du conteneur : elle borne l'ensemble des processus. Règle approximative : le nombre de workers multiplié par la mémoire par worker, plus une réserve, doit tenir sous la limite, faute de quoi le système termine des processus.
- Logs : les conteneurs écrivent les logs sur la sortie standard. Dans PHP-FPM,
catch_workers_output = yesredirige les sorties des workers vers le log principal ; sans ce réglage, elles se perdent dans le néant, selon le manuel.
request_terminate_timeout est en outre utile : il termine des requêtes isolées après un laps de temps lorsque max_execution_time n'agit pas. La manière d'exploiter des conteneurs dans un cluster est décrite dans Corriger PHP dans Kubernetes.
Conteneurs et sécurité : ce que PHP2Shell a montré
Avec PHP2Shell, les conteneurs jouent un double rôle. D'une part, ils aident : comme mesure transitoire pour CVE-2026-109618, php.net recommande de combiner memory_limit=-1 avec une limite de mémoire via conteneur ou cgroup, idéalement de sorte que seul le worker concerné soit terminé. RLIMIT_AS et RLIMIT_DATA sont inadaptés pour cela, selon php.net. Cette mesure n'est pas une protection complète et ne remplace pas la mise à jour.
D'autre part, les conteneurs sont un piège si les images ne sont pas reconstruites. Une image avec PHP 8.4.26 reste vulnérable, quel que soit le nombre de redémarrages du conteneur. Seules une reconstruction vers 8.4.27 ou plus récent et le remplacement de tous les conteneurs en cours d'exécution comblent la faille. L'état peut être contrôlé directement dans le conteneur en cours d'exécution :
docker exec <container> php -v
docker exec <container> php-fpm -v
docker exec <container> php -r 'var_dump(ini_get("memory_hard_limit_percent"));'
Si la dernière commande renvoie bool(false), PHP ne connaît pas la directive introduite avec les versions corrigées ; selon le manuel, la version est alors concernée. À long terme, seule une reconstruction automatique aide, comme décrit dans CI/CD : reconstruire automatiquement les images PHP.
Fixez dans le Dockerfile la version exacte de PHP dans le tag et augmentez-la de façon délibérée. On peut ainsi retracer dans le code quand quelle version a été déployée.
Comment PHP SOS aide-t-il concrètement ?
Lors du durcissement de serveur pour serveurs web PHP, nous nous occupons aussi des conteneurs :
- Contrôler les images : image de base, version de PHP, extensions et configuration de chaque image.
- Durcir la configuration : ini de production, liste d'extensions allégée, limites de workers et de mémoire adaptées.
- Mettre en place la reconstruction : un déroulement qui reconstruit et déploie les images à chaque nouvelle version de PHP.
- Contrôler l'exécution : nous prouvons que la version corrigée tourne dans chaque conteneur en cours d'exécution.
Questions fréquentes
Quelle variante de l'image PHP est la bonne ?
Pour Nginx ou un autre proxy, la variante fpm ; pour une architecture simple avec Apache, la variante apache ; pour les scripts et les tâches cron, la variante cli. Les variantes Alpine sont plus petites, mais reposent sur musl au lieu de glibc, ce qui se remarque avec certaines extensions.
PHP est-il mis à jour automatiquement dans le conteneur ?
Non. Un conteneur en cours d'exécution ne change pas. Vous devez reconstruire l'image avec la nouvelle version de PHP et redémarrer les conteneurs. Ce n'est qu'alors que la version corrigée tourne.
Comment memory_limit et la limite du conteneur interagissent-ils ?
memory_limit limite chaque requête PHP prise isolément, la limite du conteneur limite le conteneur entier. Les deux doivent concorder : le nombre de workers multiplié par la mémoire par worker doit rester sous la limite du conteneur.
Ai-je besoin d'un php.ini dans les conteneurs ?
Oui. Les images officielles fournissent php.ini-development et php.ini-production comme modèles. Pour la production, la documentation de l'image recommande expressément le modèle de production ; les réglages personnalisés vont dans conf.d.