Table of Contents
Ottimizzazione di Apache con PHP
Anzitutto si verificare quale MPM (Multi-Processing Module) è in uso:
apachectl -V | grep 'Server MPM' Server MPM: prefork
I moduli disponibili installati dal pacchetto apache2 sono event, prefork e worker.
Per una configurazione Apache + PHP-FPM, il modulo MPM event è la scelta preferita. Offre migliori prestazioni, scalabilità ed efficienza gestendo le connessioni in modo asincrono, mentre PHP-FPM elabora separatamente gli script PHP.
Modulo MPM prefork e mod-php
Con una installazione standard Debian di Apache e PHP è probabile che sia in uso il modulo prefork. Questo modulo prevede che ogni richiesta HTTP venga eseguita da un singolo thread e questo garantisce che funzionino correttamente anche le librerie non-thread-safe, come è il PHP. Un processo centrale gestisce il pool di istanze Apache che vengono attivate.
Questa modalità in generale è attivata semplicemente installando il pacchetto apache2-bin e il relativo libapache2-mod-php nella opportuna versione. Ad esempio in Debian 12 Bookworm abbiamo libapache2-mod-php8.2. In questo caso il PHP è semplicemente un modulo di Apache che viene abilitato tramite due link:
- /etc/apache2/mods-enabled/php8.2.conf
- /etc/apache2/mods-enabled/php8.2.load
In questo modo il modulo PHP viene caricato in ogni istanza del processo Apache, anche se il server deve fornire pagine statiche senza PHP. Inoltre il fatto che PHP sia not thread safe, costringe ad usare il MPM prefork, che è la configurazione più lenta possibile.
La configurazione del modulo è in /etc/apache2/mods-available/mpm_prefork.conf. Ad esempio è possibile aumentare il numero massimo di workers attivabili, ecc:
StartServers 5 MinSpareServers 5 MaxSpareServers 10 MaxRequestWorkers 150 MaxConnectionsPerChild 0
Modulo MPM event, proxy_fcgi e php-fpm
Secono le raccomandazioni più recenti tuttavia il modo più efficiente per eseguire Apache + PHP è tramite il modulo Apache proxy_fcgi che si interfaccia con il motore PHP tramite php-fpm (PHP FastCGI Process Manager).
I pacchetti Debian 12 da installare sono:
- libapache2-mod-fcgid
- php-fpm che dipende dalla specifica versione php8.2-fpm
Il modulo fcgid dovrebbe essere attivato automaticamente durante l'installazione del pacchetto, verificare che esistano i link simbolici:
- /etc/apache2/mods-enabled/fcgid.conf
- /etc/apache2/mods-enabled/fcgid.load
Il modulo proxy_fcgi invece va attivato manualmente:
a2enmod proxy_fcgi
È necessario anche attivare la configurazione per collegare Apache al motore php-fpm, eseguendo il comando:
a2enconf php8.2-fpm
In questo modo viene creato il link /etc/apache2/conf-enabled/php8.2-fpm.conf. Questo file indica ad Apache come gestire i file PHP, cioè interagendo con l'engine PHP tramite il socket /run/php/php8.2-fpm.sock.
Per sicurezza verifichiamo che il modulo legacy mod-php sia disabilitato e disinstalliamo definitivamente il pacchetto:
a2dismod php8.2 dpkg --purge libapache2-mod-php8.2
In questa configurazione l'engine PHP è in effetti un servizio che può essere gestito con i comandi standard systemctl (start, stop, status, ecc.):
systemctl status php8.2-fpm
Infine si cambia il modulo MPM da prefork a event:
a2dismod mpm_prefork a2enmod mpm_event systemctl restart apache2.service
Controllare che le pagine PHP siano correttamente interpretate e che il modulo MPM event sia effettivamente in uso:
apachectl -V | grep 'Server MPM' Server MPM: event
Altri moduli Apache consigliati
- setenvif
- actions
- alias
- headers
Configurazione
Le impostazioni PHP che nell'installazione legacy mpm-prefork e mod-php andavano nel file /etc/php/8.2/apache2/php.ini
vanno impostate in /etc/php/8.2/fpm/php.ini. Per renderle effettive è sufficiente riavviare il servizio PHP:
systemctl reload php8.2-fpm.service
Con la configurazione legacy mpm-prefork e mod-php le direttive per la configurazione dell'engine PHP potevano essere incluse nella configurazione di apache tramite php_value
, php_flag
, php_admin_value
e php_admin_flag
(vedere How to change configuration settings). Ad esempio in un VirtualHost potevamo avere:
<VirtualHost *:80> ... php_admin_flag display_errors On </VirtualHost>
Con la configurazione proxy_fcgi e php-fpm predefinita abbiamo una sola istanza dell'engine PHP che viene configurata dal file /etc/php/8.2/fpm/pool.d/www.conf. In questo file viene configurato il socket di comunicazione Apache - PHP e si possono mettere le varie opzioni, ad esempio:
listen = /run/php/php8.2-fpm.sock ... php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -i -f www@my.domain.com php_flag[display_errors] = on
Questa configurazione vale per tutti gli eventuali VirtualHost esistenti, poiché il file /etc/apache2/conf-enabled/php8.2-fpm.conf indica genericamente quale socket utilizzare:
<FilesMatch ".+\.ph(?:ar|p|tml)$"> SetHandler "proxy:unix:/run/php/php8.2-fpm.sock|fcgi://localhost" </FilesMatch>
Configurazione differenziata per VirtualHost
Se si desidera avere una configurazione PHP differente in base al VirtualHost è necessario provvedere come segue:
- Creare un file ad esempio /etc/php/8.2/fpm/pool.d/www.domain.tld.conf cona la configurazione PHP ad-hoc per il VirtualHost. Deve usare un socket diverso da quelli esistenti (vedi esempio sotto).
- Riavviare il servizio php8.2-fpm.service.
- Nella configurazione del VirtualHost dichiarare che l'handler PHP è il socket creato sopra.
Questo è un esempio di file /etc/php/8.2/fpm/pool.d/www.domain.tld.conf, per creare una nuova istanza del php-fpm:
[www.domain.tld] user = www-data group = www-data listen = /run/php/php-fpm.www.domain.tld.sock listen.owner = www-data listen.group = www-data pm = dynamic pm.max_children = 5 pm.start_servers = 2 pm.min_spare_servers = 1 pm.max_spare_servers = 3
Queste sono le righe da aggiungere nella sezione VirtualHost:
<IfModule proxy_fcgi_module> <FilesMatch ".+\.ph(?:ar|p|tml)$"> SetHandler "proxy:unix:/run/php/php-fpm.www.domain.tld.sock|fcgi://localhost" </FilesMatch> </IfModule>
Web Resources
- Running PHP with fcgid -
Se si esegue Apache 2.4 è preferibile il metodo php-fpm.