# Gestire PHP nei container

> Gestire PHP nel container: varianti di immagine, php.ini di produzione, estensioni, limiti di memoria, log e aggiornamenti. Con esempi e legame con PHP2Shell.

Fonte: https://phpsos.de/it/php/php-in-containern/  
Stato: 25/10/2026  
Fornitore: PHP SOS, Assistenza di emergenza PHP e sicurezza dei server. Assistenza immediata su WhatsApp: https://wa.me/491736494914?text=Buongiorno%20PHP%20SOS%2C%20abbiamo%20bisogno%20di%20aiuto%20con%20il%20nostro%20server%20PHP.%20Azienda%3A%20%E2%80%A6%20Sito%20web%3A%20%E2%80%A6

**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](https://phpsos.de/it/php2shell/docker-container-patchen/).

## 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:

```dockerfile
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:

```ini
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.

1. **Numero di worker:** `pm.max_children` nel pool FPM stabilisce quante richieste vengano elaborate contemporaneamente. Ogni worker può occupare fino a `memory_limit`.
2. **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.
3. **Log:** i container scrivono i log sullo standard output. In PHP-FPM `catch_workers_output = yes` indirizza 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](https://phpsos.de/it/server/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:

```bash
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](https://phpsos.de/it/blog/php-images-in-ci-neu-bauen/).

> **Consiglio:**
> 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](https://phpsos.de/it/leistungen/server-haertung/) 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.

## Fonti

- [Immagine ufficiale Docker: PHP](https://hub.docker.com/_/php)
- [Manuale PHP: configurazione di FPM](https://www.php.net/manual/en/install.fpm.configuration.php)
- [php.net: bollettino di sicurezza del 21/10/2026](https://www.php.net/)
