====== Ottimizzazione di Apache con PHP ======
Anzitutto si verificare quale MPM (**[[https://httpd.apache.org/docs/current/mpm.html|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 **[[https://httpd.apache.org/docs/current/mod/prefork.html|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 **[[https://cwiki.apache.org/confluence/display/httpd/php|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 [[https://www.php.net/manual/en/configuration.changes.php|How to change configuration settings]]). Ad esempio in un VirtualHost potevamo avere:
...
php_admin_flag display_errors On
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:
SetHandler "proxy:unix:/run/php/php8.2-fpm.sock|fcgi://localhost"
===== 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:
SetHandler "proxy:unix:/run/php/php-fpm.www.domain.tld.sock|fcgi://localhost"
===== Web Resources =====
* **[[https://cwiki.apache.org/confluence/display/httpd/php|Running PHP on Apache httpd]]**
* **[[https://cwiki.apache.org/confluence/display/httpd/PHP-FPM|High-performance PHP on apache httpd 2.4.x using mod_proxy_fcgi and php-fpm]]**
* **[[https://cwiki.apache.org/confluence/display/HTTPD/Php-fcgid|Running PHP with fcgid]]** - :!: Se si esegue Apache 2.4 è preferibile il metodo php-fpm.
* **[[https://computingpost.medium.com/php-8-2-how-to-install-on-debian-11-or-10-74bb37b281d4|PHP 8.2 — How to Install on Debian 11 or 10]]**
* **[[https://www.alessioligabue.it/blog/apache-ssl-php-fpm-debian|Installare Apache, HTTPS e PHP-FPM in Debian 12]]**