User Tools

Site Tools


doc:appunti:linux:sa:apache_php_optimization

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:

  1. 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).
  2. Riavviare il servizio php8.2-fpm.service.
  3. 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

doc/appunti/linux/sa/apache_php_optimization.txt · Last modified: 2025/02/28 12:35 by niccolo