Cos’è PHP-FPM | Installare e configurare PHP-FPM
PHP-FPM è un gestore di processi FastCGI in cui processi worker avviati in anticipo ricevono le richieste PHP che un server web gli passa e le elaborano. Su un server AlmaLinux 9 con Apache, questa guida verifica se è installato e come sono impostati i pool e i socket di ciascun sito, e arriva fino al test della configurazione e al controllo dello stato con l'output reale.
Apache può anche eseguire PHP direttamente con mod_php, ma se lo affidi a PHP-FPM, server web e PHP restano separati. Nginx non può eseguire PHP direttamente, quindi passa le richieste a un processo FastCGI come PHP-FPM. Per questo un solo PHP-FPM si può collegare sia ad Apache sia a Nginx. Le impostazioni dei pool e la struttura dei socket più sotto valgono così come sono anche quando colleghi PHP-FPM a Nginx.
1️⃣ Cos'è PHP-FPM: la differenza tra CGI e FastCGI
CGI (Common Gateway Interface) è il metodo standard con cui un server web esegue un programma esterno per generare contenuti dinamici, e avvia di nuovo il programma a ogni richiesta in arrivo. Il costo di creare e rimuovere un processo per ogni richiesta si accumula, e più gli accessi aumentano, più il server risponde lentamente.
FastCGI elimina questo costo avviando il programma in anticipo ed elaborando le richieste una dopo l'altra. È la differenza tra accendere e spegnere il computer a ogni utilizzo e usare subito un computer già acceso. PHP-FPM (FastCGI Process Manager) è il gestore che esegue PHP tramite FastCGI ed è incluso in PHP dalla versione 5.3.3.
Per ogni pool, cioè un gruppo di worker, PHP-FPM avvia in anticipo il numero di worker stabilito; un worker libero riceve la richiesta che il server web passa attraverso il socket, la elabora e aspetta la successiva. I file statici come immagini e CSS sono serviti direttamente dal server web, e solo i file PHP passano a PHP-FPM. Cambia soltanto il modo in cui il server web passa le richieste al socket: Apache usa il modulo mod_proxy_fcgi e Nginx usa la direttiva fastcgi_pass.
2️⃣ Installare PHP-FPM: controllare il pacchetto e installare con dnf
Se hai installato PHP con dnf su un server della famiglia RHEL, il pacchetto php-fpm è stato installato insieme. Controlla prima con rpm se è installato. Il processo di installazione di PHP è lo stesso di Installare APM su Rocky Linux.
rpm -qa | grep php-fpmphp-fpm-8.3.36-1.module_php.8.3.el9.remi.x86_64Se l'output è vuoto, non è installato; installalo con dnf.
dnf -y install php-fpmQuando l'installazione finisce, riesegui lo stesso comando rpm per verificare che venga mostrato il nome del pacchetto.
3️⃣ Configurare PHP-FPM: il pool www.conf, il socket e le modalità statica e dinamica
I file di configurazione sono due: la configurazione generale [/etc/php-fpm.conf] e la configurazione dei pool [/etc/php-fpm.d/www.conf]. Le righe da guardare per prime nel pool predefinito www.conf sono listen e pm, e i valori subito dopo l'installazione sono questi.
grep -E '^(listen|pm) ' /etc/php-fpm.d/www.conflisten = /run/php-fpm/www.sock
pm = dynamiclisten è il punto in cui il server web passa le richieste, e il valore predefinito della versione 8.3 è il socket Unix [/run/php-fpm/www.sock]. Il valore predefinito delle versioni vecchie, [127.0.0.1:9000], riceve le richieste su una porta TCP. All'interno dello stesso server il socket è più leggero perché salta la procedura di connessione tramite porta, e con listen.owner e listen.group puoi limitare l'accesso come con i permessi dei file.
🔲 Impostare la modalità statica e dinamica
pm è il modo in cui si avviano i worker, e lo imposti su uno tra static, dynamic e ondemand. La modalità statica tiene sempre avviato il numero scritto in pm.max_children, e l'impostazione qui sotto mantiene 100 worker.
pm = static
pm.max_children = 100La modalità dinamica è quella predefinita e fa salire o scendere il numero di worker in base al volume di richieste. L'impostazione qui sotto ne avvia 12 all'inizio, mantiene tra 6 e 18 worker liberi e arriva a un massimo di 120.
pm = dynamic
pm.max_children = 120
pm.start_servers = 12
pm.min_spare_servers = 6
pm.max_spare_servers = 18La modalità ondemand avvia i worker solo quando arriva una richiesta e li chiude dopo che è trascorso pm.process_idle_timeout; per questo va bene per i siti con pochi accessi e non per quelli con molti accessi.
Le tre modalità si distinguono per il momento in cui avviano i worker e per il modo in cui il loro numero sale e scende.
| Modalità | Come vengono avviati i worker | Siti adatti |
|---|---|---|
| static (statico) | Tiene sempre avviato il numero scritto in pm.max_children | Siti con molti accessi |
| dynamic (dinamico) | Predefinito · sale e scende entro pm.start_servers, pm.min_spare_servers e pm.max_spare_servers in base al volume di richieste | Siti con accessi che salgono e scendono |
| ondemand | Avvia solo quando arriva una richiesta e chiude dopo che è trascorso pm.process_idle_timeout | Siti con pochi accessi |
max_children si stabilisce dividendo la memoria del server per la memoria usata da un worker. Anche quando si accumulano gli avvisi su [max_children], non alzarlo subito; prima individua nei log quali richieste hanno riempito i worker.
La memoria e il limite di upload si impostano in php.ini, la configurazione generale di PHP, e si regolano insieme al numero di worker in base al sito che gestisci.
memory_limit = 1024M
post_max_size = 128M
upload_max_filesize = 128MI tre valori sono il limite di memoria che può usare un singolo script PHP e la dimensione dei file che si possono caricare in una volta, e si applicano solo dopo aver riavviato PHP-FPM.
🔲 Impostare un pool per account del sito
Se i siti sono più di uno, non si condivide un unico www.conf: si crea un file di pool per ogni account e si separano l'account di esecuzione e il socket. Il PHP di un sito non può leggere i file di un altro account, e il numero di worker si stabilisce sito per sito.
vi /etc/php-fpm.d/siteuser.confNel file si scrivono il nome del pool, l'account di esecuzione, il percorso del socket e il numero di worker.
[siteuser]
user = siteuser
group = nobody
listen = /run/php-fpm/siteuser.sock
listen.owner = siteuser
listen.group = nobody
listen.mode = 0660
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35
chdir = /home/siteuser/wwwlisten.owner e listen.group sono il proprietario e il gruppo del file del socket, e PHP-FPM crea il socket con questi valori all'avvio. Se il server web gira con l'account nobody, scrivi nobody in listen.group; se gira con l'account apache, scrivi apache, in modo che il server web possa aprire il socket.
listen.owner = siteuser
listen.group = nobody
listen.mode = 0660Queste tre righe vanno in ogni file di pool, e dopo aver cambiato i valori bisogna riavviare perché il socket venga ricreato con i nuovi permessi.
🔲 Impostare slowlog
slowlog è un file che registra dove si trovava l'esecuzione delle richieste durate più di request_slowlog_timeout, e con il valore 0 non registra nulla. Quando cerchi la causa delle richieste lente, attivalo indicando un tempo in secondi, come 3s.
slowlog = /var/log/php-fpm/www-slow.log
request_slowlog_timeout = 0Il file registrato conserva il percorso dello script della richiesta lenta e la funzione in esecuzione in quel momento, così puoi vedere quale plugin o quale codice ha richiesto tempo.
4️⃣ Integrazione con Apache: impostazioni del VirtualHost e permessi del socket
Apache passa al socket del pool le richieste dei file PHP con il modulo mod_proxy_fcgi. Inserisci una riga SetHandler nel FilesMatch dentro il VirtualHost, e per ogni sito scrivi il socket del suo account.
# Un VirtualHost per account del sito · in SetHandler va il socket di quell'account (al posto di SetHandler si può collegare anche con ProxyPassMatch)
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
DocumentRoot /home/siteuser/www
<Directory /home/siteuser/www>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
<FilesMatch \.php$>
SetHandler "proxy:unix:/run/php-fpm/siteuser.sock|fcgi://localhost"
</FilesMatch>
</VirtualHost>DocumentRoot e Directory sono la radice web di quell'account, e -Indexes in Options impedisce che l'elenco delle cartelle venga mostrato nel browser.
🔲 Impostare i permessi del socket
Quando il pool parte, il socket viene creato con i valori di listen.owner, listen.group e listen.mode, e con ls controlli che i permessi siano corretti.
ls -l /run/php-fpm/totale 4
srw-rw---- 1 siteuser_a nobody 0 ott 22 23:34 siteuser_a.sock
-rw-r--r-- 1 root root 7 ott 26 03:00 php-fpm.pid
srw-rw---- 1 siteuser_b nobody 0 ott 22 23:34 siteuser_b.sock
srw-rw----+ 1 root root 0 ott 22 23:34 www.sockSe i permessi non coincidono e il server web non riesce ad aprire il socket, i visitatori ricevono un errore 503; per correggere subito senza riavviare, imposta proprietario e permessi con chown e chmod.
Questa è la sintassi attuale, che separa utente e gruppo con i due punti.
chown siteuser:nobody /run/php-fpm/siteuser.sockDopo aver cambiato il proprietario, imposta i permessi a 660.
chmod 660 /run/php-fpm/siteuser.sockQuesta è la sintassi vecchia, che separa utente e gruppo con un punto, e chown la esegue ancora così com'è su AlmaLinux 9.
chown siteuser.nobody /run/php-fpm/siteuser.sockDopo aver cambiato il proprietario, imposta i permessi a 660.
chmod 660 /run/php-fpm/siteuser.sockIl risultato delle due sintassi è lo stesso: qualunque usi, il proprietario del socket diventa siteuser e il gruppo diventa nobody.
🔲 Integrazione con Nginx: la direttiva fastcgi_pass
In Nginx, il location per i file PHP dentro il blocco server passa le richieste al socket dello stesso pool con fastcgi_pass.
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/run/php-fpm/siteuser.sock;
}Se Nginx gira con l'account nginx, nel file del pool bisogna scrivere nginx in listen.group perché possa aprire il socket.
5️⃣ Test della configurazione e riavvio: php-fpm -t e systemctl
Dopo aver cambiato la configurazione, non riavviare subito; fai prima un controllo della sintassi con php-fpm -t. Se in un file di pool c'è un refuso, al riavvio cade tutto PHP-FPM e tutti i siti ricevono un 503.
php-fpm -t[26-Oct-2026 17:33:45] NOTICE: configuration file /etc/php-fpm.conf test is successfulSe il controllo va a buon fine, viene mostrato il messaggio [test is successful] insieme al percorso del file di configurazione, e poi applichi la modifica a PHP-FPM. Una modifica che richiede di ricreare il socket, come il percorso del socket o listen.owner, si applica con restart. Se su un server in produzione hai cambiato solo valori come il numero di worker, applicala con reload.
systemctl restart php-fpmSe hai modificato il VirtualHost, riavvia anche Apache.
systemctl restart httpdRegistralo con enable perché venga eseguito automaticamente quando il server viene riacceso.
systemctl enable php-fpmControlla se è registrato con is-enabled.
systemctl is-enabled php-fpmenabledCon status controlla che per ogni pool ci siano worker in esecuzione.
systemctl status php-fpm● php-fpm.service - The PHP FastCGI Process Manager
Loaded: loaded (/usr/lib/systemd/system/php-fpm.service; enabled; preset: disabled)
Active: active (running) since x
Process: 3934033 ExecReload=/bin/kill -USR2 $MAINPID (code=exited, status=0/SUCCESS)
Main PID: 1333314 (php-fpm)
Status: "Processes active: 4, idle: 21, Requests: x, slow: 0, Traffic: x"
Tasks: x
Memory: x
CPU: x
CGroup: /system.slice/php-fpm.service
├─ 41920 "php-fpm: pool siteuser_a"
├─ 94143 "php-fpm: pool siteuser_b"
├─1333314 "php-fpm: master process (/etc/php-fpm.conf)"
├─3934078 "php-fpm: pool www"
└─4009016 "php-fpm: pool siteuser_a"
ott 26 03:00:01 server.example.com systemd[1]: Reloading The PHP FastCGI Process Manager...
ott 26 03:00:01 server.example.com systemd[1]: Reloaded The PHP FastCGI Process Manager.Nella riga Status, active e idle sono i worker che stanno elaborando richieste in questo momento e quelli liberi, e CGroup elenca i worker per nome del pool. Il nome host e i nomi dei pool nell'output sono stati sostituiti con valori di esempio.
🔢 FAQ & contenuti consigliati
Cache
Cache: definizione e tutti gli ambiti in cui si usa il caching
Spiega, campo per campo, come le richieste che trovano risposta nella cache non arrivano mai a un worker PHP-FPM.
Server cache
Installare e configurare Varnish Cache su Apache e Nginx
I passaggi di installazione per mettere un server cache davanti al server web e ridurre così le richieste PHP stesse.
Linux
15 categorie di comandi Linux
Una tabella che classifica i comandi in 15 categorie, inclusi rpm, grep e systemctl usati in questo articolo.
ℹ️ Informativa sull'affiliazione
I contenuti di questo sito includono link di affiliazione. Se un visitatore acquista un prodotto o un servizio tramite uno di questi link, il sito riceve una commissione dal venditore. In questo processo l'importo pagato dall'acquirente (durante le promozioni l'importo scende↓) non aumenta. Prezzi, sconti e disponibilità indicati si riferiscono al momento della stesura e possono differire da quelli reali: prima di acquistare verifica sempre presso il venditore. I prodotti vengono scelti e valutati secondo criteri propri, e le commissioni non influiscono sull'ordine di presentazione né sul contenuto delle valutazioni.