====== 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]]**