In breve: per gestire PHP nei container si sceglie la variante adatta dell'immagine ufficiale (fpm, apache o cli), si attiva il php.ini di produzione, si installano solo le estensioni necessarie e si impostano limiti di memoria e di processi coerenti tra loro. I container sono immutabili: un aggiornamento di sicurezza di PHP come quello per PHP2Shell ha effetto solo quando l'immagine è stata ricostruita e ogni container riavviato. Questa ricostruzione deve quindi essere un processo fisso in ogni esercizio con container.
Perché PHP nei container?
I container impacchettano PHP, estensioni e configurazione in un'immagine che gira allo stesso modo su ogni server. Per le aziende significa: meno sorprese tra test e produzione, ripristino più rapido e stati di versione chiari. Per la sicurezza significa però anche un nuovo obbligo: in un container nessuno installa automaticamente gli aggiornamenti.
Questa pagina tratta l'esercizio corrente. Come applicare concretamente la patch contro PHP2Shell ai container esistenti è spiegato in Aggiornare PHP nei container Docker.
Scegliere la variante di immagine giusta
| Variante | Contenuto | Impiego tipico |
|---|---|---|
php:<version>-fpm |
PHP-FPM, richiede un server web a monte | produzione con Nginx, Caddy o un ingress |
php:<version>-apache |
Apache con mod_php, per impostazione predefinita mpm_prefork | strutture semplici, applicazioni più vecchie |
php:<version>-cli |
riga di comando, unica variante a contenere anche php-cgi | cronjob, worker di code, passaggi di build |
…-alpine |
basata su Alpine Linux con musl | immagini piccole, con alcune estensioni servono adattamenti |
…-bookworm, …-trixie |
basata sulla versione Debian indicata | base fissa per build riproducibili |
Per i nuovi progetti si raccomanda di norma la variante fpm con un container di server web separato. Con mod_php il team PHP vede, in relazione a PHP2Shell, il rischio più alto; chi usa l'immagine apache gestisce proprio questa modalità di esecuzione.
Costruire un'immagine di produzione
Un esempio snello per un'applicazione con accesso a MySQL:
FROM php:8.4-fpm-alpine
# Attivare la configurazione di produzione (fortemente raccomandata dalla documentazione dell'immagine)
RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"
# Solo le estensioni necessarie
RUN docker-php-ext-install -j"$(nproc)" pdo_mysql
# Impostazioni proprie
COPY zz-sicherheit.ini "$PHP_INI_DIR/conf.d/"
# Il codice appartiene a root; i worker FPM girano come www-data e possono solo leggerlo
COPY . /var/www/html
Gli script di supporto dell'immagine si occupano di costruire le estensioni: docker-php-ext-configure per le opzioni, docker-php-ext-install per costruire, docker-php-ext-enable per attivare, ad esempio dopo pecl install. Se con docker-php-source si estrae il codice sorgente, secondo la documentazione andrebbe eliminato di nuovo nello stesso layer. Il file zz-sicherheit.ini potrebbe avere questo aspetto:
expose_php = Off
display_errors = Off
log_errors = On
session.use_strict_mode = 1
session.cookie_httponly = 1
Due ulteriori principi rendono le immagini più robuste. Primo: l'immagine distribuita contiene solo ciò che serve in esecuzione; compilatori, cache dei pacchetti e file di test appartengono a una fase di build separata. Secondo: l'utente con cui gira PHP deve poter scrivere solo dove è necessario, ad esempio nelle directory di upload o di cache su volumi montati. Molti team fanno inoltre girare il container con file system in sola lettura. Un file PHP introdotto abusivamente ha allora molta più difficoltà a restare in modo permanente, e ogni riavvio ripristina lo stato pulito dell'immagine. Ciò non sostituisce un'indagine dopo un incidente, ma riduce sensibilmente la superficie d'attacco.
Processi, memoria e log nel container
Tre regolazioni determinano se un container PHP giri in modo stabile.
- Numero di worker:
pm.max_childrennel pool FPM stabilisce quante richieste vengano elaborate contemporaneamente. Ogni worker può occupare fino amemory_limit. - Limite di memoria del container: limita tutti i processi insieme. Come regola approssimativa vale: numero di worker per la memoria per worker più una riserva deve rientrare nel limite, altrimenti il sistema termina dei processi.
- Log: i container scrivono i log sullo standard output. In PHP-FPM
catch_workers_output = yesindirizza l'output dei worker nel log principale; senza l'impostazione, secondo il manuale, va nel nulla.
Utile è inoltre request_terminate_timeout, che termina le singole richieste dopo un intervallo di tempo quando max_execution_time non interviene. Come gestire i container nel cluster lo descrive Aggiornare PHP in Kubernetes.
Container e sicurezza: che cosa ha mostrato PHP2Shell
Con PHP2Shell i container hanno un duplice ruolo. Da un lato sono un aiuto: come misura transitoria per CVE-2026-109618 php.net raccomanda di combinare memory_limit=-1 con un limite di memoria tramite container o cgroup, idealmente in modo che venga terminato solo il worker interessato. RLIMIT_AS e RLIMIT_DATA sono, secondo php.net, inadatti allo scopo. Questa misura non è una protezione completa e non sostituisce l'aggiornamento.
Dall'altro i container sono una trappola se le immagini non vengono ricostruite. Un'immagine con PHP 8.4.26 resta vulnerabile, per quante volte il container si riavvii. Solo una ricostruzione con la 8.4.27 o successiva e la sostituzione di tutti i container in esecuzione chiudono la vulnerabilità. Lo stato si può controllare direttamente nel container in esecuzione:
docker exec <container> php -v
docker exec <container> php-fpm -v
docker exec <container> php -r 'var_dump(ini_get("memory_hard_limit_percent"));'
Se l'ultimo comando restituisce bool(false), PHP non conosce la direttiva introdotta con le versioni corrette; secondo il manuale la versione è allora interessata. A lungo termine aiuta solo una ricostruzione automatica, come descritto in CI/CD: ricostruire automaticamente le immagini PHP.
Definisca nel Dockerfile l'esatta versione di PHP nel tag e la aumenti consapevolmente. Così nel codice si può ricostruire quando sia stata distribuita quale versione.
Come aiuta concretamente PHP SOS?
Nel rafforzamento dei server web PHP ci occupiamo anche dei container:
- Verificare le immagini: immagine di base, versione di PHP, estensioni e configurazione di ogni immagine.
- Rafforzare la configurazione: ini di produzione, elenco snello delle estensioni, limiti adeguati di worker e di memoria.
- Impostare la ricostruzione: una procedura che ricostruisce e distribuisce le immagini a ogni nuova release di PHP.
- Controllare l'esecuzione: dimostriamo che in ogni container in esecuzione gira la versione corretta.
Domande frequenti
Qual è la variante giusta dell'immagine PHP?
Per Nginx o un altro proxy la variante fpm, per una struttura semplice con Apache la variante apache, per script e cronjob la variante cli. Le varianti Alpine sono più piccole, ma si basano su musl invece di glibc, il che si nota con alcune estensioni.
PHP nel container si aggiorna automaticamente?
No. Un container in esecuzione non cambia. Deve ricostruire l'immagine con la nuova versione di PHP e riavviare i container. Solo allora gira la versione corretta.
Come si comportano memory_limit e il limite del container?
memory_limit limita ogni singola richiesta PHP, il limite del container l'intero container. Entrambi devono essere coerenti: il numero di worker per la memoria per worker dovrebbe stare sotto il limite del container.
Ho bisogno di un php.ini nei container?
Sì. Le immagini ufficiali forniscono php.ini-development e php.ini-production come modelli. Per la produzione la documentazione dell'immagine raccomanda espressamente il modello di produzione; le impostazioni proprie vanno in conf.d.