Installer PHP-FPM sur Debian
PHP-FPM est une amélioration sensible de la mécanique FCGI pour PHP. Son utilisation permet d'améliorer sensiblement les performances de vos sites Internet. C'est un outil recommandé pour optimiser l'hébergement de sites générant un fort trafic. Cet article vous guide dans la mise en place de cette mécanique sur Debian, en utilisant les paquets fournit par dotdeb.org.
Ce guide est testé sur:
- Debian 6.0 Squeeze
- Debian 7.0 Wheezy
- Ubuntu 13.10 Saucy Salamander
- Ubuntu 16.04 Xenial Xerus
- Ubuntu 17.10 Artful Aardvark
Prérequis
Ce guide nécessite:
- les dépôts Debian contrib, comme décrit par Configurer les dépôts Debian contrib et non-free.
- l'un de ces serveurs HTTP:
- Apache 2, comme décrit par Installer Apache 2 sur Debian.
- Lighttpd, comme décrit par Installer Lighttpd sur Debian.
Pour Debian 6.0 Squeeze, ce guide nécessite:
- les dépôts Dotdeb, comme décrit par Configurer les dépôts Dotdeb sur Debian. Une fois la mise en place terminée, suivez la section Installation de la version de PHP 5.3 fournie par Dotdeb.
Installation
Détectez le proxy de commande (command ou sudo):
cmdProxy='command'
command type -f 'sudo' &>'/dev/null' && cmdProxy='sudo'
Détectez le nom des paquets PHP disponibles:
phpVersion='5'
if [ -n "$(command apt-cache pkgnames php-cli)" ]; then
phpVersion=''
fi
Installation de FPM
Installez le paquet logiciel:
${cmdProxy} apt-get install "php${phpVersion}-fpm" "php${phpVersion}-cli"
Installez l'extension suhosin si elle est disponible:
if [ -n "$(command apt-cache pkgnames php5-suhosin)" ]; then ${cmdProxy} apt-get -y install php5-suhosin fi
Détectez la version installée de PHP:
phpVersion="$(readlink -f /usr/bin/php | cut -c 13-)"
Détectez le chemin des fichiers de configuration de PHP:
test -d '/etc/php/' \
&& phpEtcPath="/etc/php/${phpVersion}"
test -z "${phpEtcPath}" -a -d '/etc/php5' && phpEtcPath='/etc/php5'
Sauvegardez le fichier de configuration modèle de php-fpm:
test -e "${phpEtcPath}/fpm/pool.d/www.conf" \
&& ${cmdProxy} dpkg-divert --divert "${phpEtcPath}/fpm/pool.d/www.conf-dist" \
--rename "${phpEtcPath}/fpm/pool.d/www.conf"
Créez le fichier de configuration de PHP-FPM:
command test -e "${phpEtcPath}/fpm/pool.d/www.conf" \
|| ${cmdProxy} cp "${phpEtcPath}/fpm/pool.d/www.conf-dist" "${phpEtcPath}/fpm/pool.d/www.conf"
Configurez PHP-FPM pour attendre les connexions sur un socket Unix, et pour autorisez l'exécution de scripts PHP durant jusqu'à 600 secondes:
if [ -e "${phpEtcPath}/fpm/pool.d/www.conf" ]; then
test "${phpVersion}" = '5' && ${cmdProxy} sed -i \
-e 's|^listen =.*$|listen = /var/run/php-fpm.sock|' \
-e 's|^;*request_terminate_timeout.*|request_terminate_timeout = 605|' \
"${phpEtcPath}/fpm/pool.d/www.conf"
${cmdProxy} sed -i \
-e 's|^;*pm.status_path.*|pm.status_path = /php-fpm-status|' \
-e 's|^;*ping.path.*|ping.path = /php-fpm-ping|' \
"${phpEtcPath}/fpm/pool.d/www.conf"
fi
Important: Il est maintenant nécessaire de redémarrer le service PHP-FPM à chaque installation d'un module PHP:
if [ -n "$(command find "${phpEtcPath}/fpm/pool.d/" -name '*.conf')" -a -e "/etc/init.d/php${phpVersion}-fpm" ]; then
${cmdProxy} service "php${phpVersion}-fpm" 'restart'
fi
Configurez la rotation des fichiers journaux:
if [ ! -e "/etc/logrotate.d/php${phpVersion}-fpm" ]; then
command echo -e "/var/log/php${phpVersion}-fpm.log {
\trotate 12
\tweekly
\tmissingok
\tnotifempty
\tcompress
\tdelaycompress
\tpostrotate
\t\tinvoke-rc.d php${phpVersion}-fpm force-reload > /dev/null
\tendscript
}" \
| ${cmdProxy} tee "/etc/logrotate.d/php${phpVersion}-fpm"
fi
Finalisation
Ce guide recommande:
- L'ajustement de la configuration de PHP, comme décrit par Améliorer la configuration initiale de PHP sur Debian.
- La journalisation des erreurs PHP via Syslog, comme décrit par Journaliser les erreurs PHP avec Syslog.
- La mise en place du cache d'op-code APC, comme décrit par Installer l'extension PHP APC sur Debian.
Configuration du serveur HTTP
Configuration de Apache 2
Si le système est récent, activez la configuration d'Apache fournie:
if [[ -e "/etc/apache2/conf-available/php${phpVersion}-fpm.conf" ]]; then
${cmdProxy} a2enmod proxy_fcgi setenvif
${cmdProxy} a2enconf "php${phpVersion}-fpm"
${cmdProxy} service apache2 force-reload
fi
Installez le module FastCGI d'Apache 2:
if [ -d '/etc/apache2' -a ! -e "/etc/apache2/conf-available/php${phpVersion}-fpm.conf" ]; then
${cmdProxy} apt-get install libapache2-mod-fastcgi
fi
Créez un fichier de configuration pour utiliser PHP-FPM avec le module FastCGI:
if [ -d '/etc/apache2' -a ! -e "/etc/apache2/conf-available/php${phpVersion}-fpm.conf" ]; then
${cmdProxy} wget 'https://raw.github.com/biapy/howto.biapy.com/master/apache2/php-fpm/php-fpm.load' \
--quiet --no-check-certificate --output-document='/etc/apache2/mods-available/php-fpm.load'
${cmdProxy} wget 'https://raw.github.com/biapy/howto.biapy.com/master/apache2/php-fpm/php-fpm.conf' \
--quiet --no-check-certificate --output-document='/etc/apache2/mods-available/php-fpm.conf'
fi
Activez le module php-fpm pour Apache 2:
if [ -d '/etc/apache2' -a ! -e "/etc/apache2/conf-available/php${phpVersion}-fpm.conf" ]; then
${cmdProxy} a2dismod "php${phpVersion}"
${cmdProxy} a2enmod php-fpm fastcgi actions
fi
Rechargez la configuration d'Apache 2:
[[ -x '/etc/init.d/apache2' ]] && ${cmdProxy} service 'apache2' 'force-reload'
Si la configuration fonctionne, installez la version MPM-Worker d'Apache 2:
if [ -d '/etc/apache2' -a -n "$(command apt-cache pkgnames apache2-mpm-worker)" ]; then
${cmdProxy} apt-get install apache2-mpm-worker
fi
Configuration de lighttpd
Configurez Lighttpd pour utiliser php-fpm:
if [ -d '/etc/lighttpd' ]; then
echo '# /usr/share/doc/lighttpd-doc/fastcgi.txt.gz
# http://redmine.lighttpd.net/projects/lighttpd/wiki/Docs:ConfigurationOptions#mod_fastcgi-fastcgi
## Start an FastCGI server for php (needs the php fpm package)
fastcgi.server += ( ".php" =>
((
"socket" => "/var/run/php-fpm.sock"
))
)' \
| ${cmdProxy} tee '/etc/lighttpd/conf-available/15-fastcgi-php-fpm.conf'
fi
Activez la nouvelle configuration:
if [ -x '/usr/sbin/lighty-enable-mod' ]; then
${cmdProxy} lighty-disable-mod fastcgi-php
${cmdProxy} lighty-enable-mod fastcgi-php-fpm
fi
Rechargez la configuration de lighttpd:
[[ -x '/etc/init.d/lighttpd' ]] && ${cmdProxy} service 'lighttpd' 'force-reload'
Résolution des problèmes
.htaccess: Invalid command 'php_flag'
Si le journal d'erreur d'Apache 2 contient:
.htaccess: Invalid command 'php_flag', perhaps misspelled or defined by a module not included in the server configuration
L'un des sites hébergé utilise la directive "php_flag" dans un fichier .htaccess. Cette directive est fournie par le mod_php5 d'Apache 2, et n'est pas compatible avec FastCGI, ou PHP-FPM.
Pour corriger l'erreur, commentez les lignes en faute dans le fichier .htaccess, et de créer un fichier ini de configuration équivalent dans /etc/php5/conf.d/.
FastCGI: comm with server aborted : idle timeout
Si le journal d'erreur d'Apache 2 contient:
FastCGI: comm with server "/var/lib/apache2/fastcgi/php5.fastcgi" aborted: idle timeout (610 sec)
Le temps d'exécution d'une page PHP dépasse les 610s. Cela arrive, par exemple, lors de la mise à jour d'une application Web.
Pour corriger l'erreur, augmentez la valeur de l'option -idle-timeout dans le fichier /etc/apache2/mods-available/php5-fpm.conf:
FastCGIExternalServer /var/lib/apache2/fastcgi/php5.fastcgi -socket /var/run/php5-fpm.sock -idle-timeout 910
Augmentez aussi la valeur de l'option request_terminate_timeout dans le fichier /etc/php5/fpm/pool.d/www.conf (la valeur doit rester légèrement inférieure à celle de idle-timout (voir ci-dessus)):
request_terminate_timeout = 905
Ces deux valeurs doivent être supérieures au réglagle PHP max_execution_time.
ERROR: failed to ptrace(PEEKDATA) pid XXXXX : Input/output error (5)
Si le journal de PHP-FPM (/var/log/php5-fpm.log) contient:
ERROR: failed to ptrace(PEEKDATA) pid 25478: Input/output error (5)
Cette erreur apparaît lorsque l'option "request_slowlog_timeout" est activée. Elle correspond à un échec de création de la trace. Cela peut déclencher une indisponibilité du serveur car:
- Après l'arrêt du processus par PHP-FPM pour créer la trace de l'erreur, le processus ne redevient pas disponible à cause de l'échec de création de la trace.
- Le processus redevient disponible, mais rentre dans une boucle.
Pour résoudre ce problème, désactivez l'option "request_slowlog_timeout":
${cmdProxy} sed -i \
-e 's/^request_slowlog_timeout/;request_slowlog_timeout/' \
'/etc/php5/fpm/pool.d/'*'.conf'
Rechargez la configuration de PHP-FPM:
${cmdProxy} service 'php5-fpm' 'force-reload'
Remerciements
- Merci aux développeurs de PHP-FPM (en).
- Merci à Evolix (fr) pour Howto Nginx + PHP-FPM (fr).
- Merci à MyProd (fr) pour Apache2, PHP-FPM, FastCGI et APC cache d’Opcode (fr).
- Merci à HowtoForge (en) pour Using PHP5-FPM With Apache2 On Ubuntu 11.10 (en).
- Merci à Failover (en) pour Quick Setup: Apache Worker, FastCGI, PHP-FPM and APC (en).
- Merci à cd ~tigrou/pwet.fr (fr) pour man dpkg-divert (Administration système) - remplacer la version d'un fichier contenu dans un paquet (fr).
- Merci à Foaa (en) pour PHP, apache and fastcgi – a comprehensive overview (en).
- Merci à DerfK pour sa réponse à I/O Error with PHP5-FPM, ptrace(PEEKDATA) failed (en).