Aujourd’hui, j’ai changé la manière dont Apache et PHP interagissent ensemble.
Concrètement, au lieu d’utiliser la configuration par défaut du serveur Apache, c’est-à-dire le module mod_php
par défaut, le serveur utilisera dorénavant mod_fastcgi (fastcgi
) avec PHP-FPM (FastCGI Process Manager).
PHP : mod_php vs mod_fastcgi
La raison principale pour laquelle mod_php
utilise plus de ressources réside dans le fait que le module est chargé par le serveur même lors de requêtes pour des fichiers autres que PHP, comme des fichiers HTML ou des fichiers JavaScript.
FastCGI Process Manager (PHP-FPM) aide à réduire l’addition des ressources système utilisées en forçant le serveur à agir comme un proxy et à ne passer que les fichiers portant l’extension php à PHP-FPM.
Ce tutoriel assume que vous avez une installation Apache/PHP sous Debian qui tourne sous mod_php
, c’est-à-dire une installation standard. Les changements prennent moins de 15 minutes.
Objectifs : gagner en rapidité d’exécution et avoir une installation plus légère. On peut ainsi envisager un jour de changer Apache pour un autre serveur tout en gardant la même configuration PHP.
Apache MPM
Apache possède trois différents Multi-Processing Modules (MPMs) qui sont en charge de se connecter aux ports de la machine, accepter les requêtes et les transmettre aux processus enfants (children processes) :
Prefork: chaque processus enfant gère une connexion à la fois. C’est le mode par défaut sous Apache.
Worker: utilise plusieurs processus enfants qui gèrent chacun plusieurs connexions.
Event: ce mode a été créé pour permettre de servir plus de requêtes simultanément en délégant le temps de traitement à des processus enfants pour libérer le processus principal.
Nous sommes passés de Prefork à Worker durant la rédaction de cet article, avec des performances accrues.
Installation de mod_fastcgi et PHP-FPM
1. on vérifie que le paquet libapache2-mod-fastcgi
est disponible sur le serveur:
sudo apt-cache search libapache2-mod-fastcgi
2. si ce n’est pas le cas, la recherche ne retourne aucun résultat, cela veut dire qu’il nous manque les dépôts non-free
dans les fichiers sources d’apt
. On édite donc nos dépôts :
nano /etc/apt/sources.list
Code language: PHP (php)
et on ajoute non-free à la fin des lignes suivantes :
deb http://mirror.ovh.net/debian/ stable main contrib non-free
deb-src http://mirror.ovh.net/debian/ stable main contrib non-free
deb http://security.debian.org/ stable/updates main contrib non-free
deb-src http://security.debian.org/ stable/updates main contrib non-free
Code language: JavaScript (javascript)
3. On met à jour nos dépôts :
apt-get update && apt-get upgrade
Code language: JavaScript (javascript)
4. On installe les paquets:
apt-get install apache2-mpm-worker libapache2-mod-fastcgi php5-fpm
Code language: JavaScript (javascript)
Configurer Apache MPM Worker
On édite la configuration du MPM Worker :
nano /etc/apache2/mods-available/mpm_worker.conf
et on modifie un peu les valeurs par défaut:
StartServers 2
MinSpareThreads 25
MaxSpareThreads 75
ThreadLimit 64
ThreadsPerChild 25
MaxRequestWorkers 400
MaxConnectionsPerChild 1000
Configurer Apache avec PHP-FPM
Nous allons maintenant configurer Apache pour qu’il passe toutes les requêtes pour les fichiers PHP au conteneur PHP via FastCGI.
1. On active les modules nécessaires:
a2enmod actions alias fastcgi
2. On vérifie que PHP-FPM utilise bien les sockets:
# PHP5
# grep -E '^\s*listen\s*=\s*[a-zA-Z/]+' /etc/php5/fpm/pool.d/www.conf
# PHP7
grep -E '^\s*listen\s*=\s*[a-zA-Z/]+' /etc/php/7.0/fpm/pool.d/www.conf
Code language: PHP (php)
Cela devrait retourner la ligne suivante:
# PHP5
# listen = /var/run/php5-fpm.sock
# PHP7
listen = /run/php/php7.0-fpm.sock
Code language: PHP (php)
ce qui est la configuration par défaut depuis PHP 5 mais dans le cas contraire, on édite le fichier:
# PHP5
# nano /etc/php5/fpm/pool.d/www.conf
# PHP7
nano /etc/php/7.0/fpm/pool.d/www.conf
Code language: PHP (php)
on modifie la directive listen
avec:
# PHP5
# listen = /var/run/php5-fpm.sock
# PHP7
listen = /run/php/php7.0-fpm.sock
Code language: PHP (php)
et on redémarre php-fpm
:
# PHP5
# service php5-fpm restart
# PHP7
service php7.0-fpm restart
Code language: PHP (php)
3. On édite le fichier /etc/apache2/mods-enabled/fastcgi.conf
:
nano /etc/apache2/mods-enabled/fastcgi.conf
On remplace tout le contenu du fichier par :
AddType application/x-httpd-fastphp .php
Action application/x-httpd-fastphp /php-fcgi
# PHP5
# Alias /php-fcgi /usr/lib/cgi-bin/php5-fcgi
# FastCgiExternalServer /usr/lib/cgi-bin/php5-fcgi -appConnTimeout 10 -idle-timeout 250 -socket /var/run/php5-fpm.sock -pass-header Authorization
# PHP7
Alias /php-fcgi /usr/lib/cgi-bin/php
FastCgiExternalServer /usr/lib/cgi-bin/php -appConnTimeout 10 -idle-timeout 250 -socket /run/php/php7.0-fpm.sock -pass-header Authorization
# Apache 2.4+
Require all granted
Code language: PHP (php)
Vérifiez que votre configuration ne présente aucune erreur:
apache2ctl configtest
Vous devriez obtenir le message “Syntax OK“. Sinon, re-vérifiez votre configuration.
4. Avec PHP-FPM, le fichier php.ini change ! Il se trouve désormais à cet endroit /etc/php5/fpm/php.ini
et je vous conseille d’en vérifier la configuration.
# PHP5
# nano /etc/php5/fpm/php.ini
# PHP7
nano /etc/php/7.0/fpm/php.ini
Code language: PHP (php)
Je vous recommande d’activer la directive error_log
afin de garder une trace des erreurs PHP. Décommentez la ligne et ajoutez un chemin :
error_log = /var/log/php_errors.log
Code language: JavaScript (javascript)
Cela évite d’envoyer les messages d’erreur PHP dans la console et d’affoler PHP-FPM avec des messages d’erreur de ce type:
FastCGI: comm with server "/usr/lib/cgi-bin/php" aborted: idle timeout (250 sec)
FastCGI: incomplete headers (0 bytes) received from server "/usr/lib/cgi-bin/php"
Code language: JavaScript (javascript)
5. On désactive maintenant mod_php
:
a2dismod php5
6. On active mpm_worker
:
a2dismod mpm_prefork
a2enmod mpm_worker
et on redémarre PHP-FPM et Apache :
# PHP5
# service php5-fpm restart
# PHP7
service php7.0-fpm restart
service apache2 restart
Code language: PHP (php)
Voilà, notre serveur Apache tourne désormais avec mod_fastcgi et PHP-FPM!
Synopsis » Monter un serveur dédié de A à Z
- Serveur dédié : installation d’Apache, PHP, MySQL et Webmin
- Serveur dédié : créer la base de données MySQL et importer WordPress
- Serveur dédié : créer et activer un Virtual Host sous Apache
- Serveur dédié : changer les DNS du nom de domaine et le faire pointer vers le serveur
- Serveur dédié : sécurisation des services avec iptables et fail2ban
- Serveur dédié : sécurisation de la couche TCP/IP
- Serveur dédié : création d’un serveur mail Postfix (sécurisé avec Saslauthd et certificat SSL) et Courier (accès POP et IMAP) utilisant une base MySQL d’utilisateurs/domaines virtuels
- Serveur dédié : sécuriser Apache 2 avec ModSecurity
- Serveur dédié : CHMOD récursif sur des fichiers ou répertoires en ligne de commande
- Serveur dédié : installer APC comme système de cache et configurer Varnish comme reverse-proxy pour Apache pour améliorer les performances
- Serveur dédié : afficher la véritable IP derrière un reverse-proxy comme Varnish
- Serveur dédié : intégrer SSH à WordPress pour mettre à jour le core, les plugins et les thèmes
- Serveur dédié : installer la dernière version d’APC par SVN
- Serveur dédié : analyse des performances du serveur
- Serveur dédié : mettre à jour le noyau Debian de la Kimsufi
- Serveur dédié : sauvegarde automatique des fichiers avec Backup Manager sur le serveur de sauvegarde OVH
- Serveur dédié : configurer la limite mémoire pour PHP et Suhosin
- Bash : supprimer tous les fichiers et sous-répertoires d’un répertoire
- Serveur dédié : impossible de se connecter à un port distant
- Rsync: rapatrier les fichiers du serveur à la maison
- Bash : réparer les tables MySQL en cas de crash
- Serveur dédié : création d’une seedbox avec Transmission
- Serveur dédié : des paquets LAMP à jour sous Debian
- Serveur dédié : mise à jour vers Debian 7 Wheezy
- Serveur dédié : activer X11 forwarding pour SSH
- Serveur dédié : optimiser toutes les images JPG et PNG avec OptiPNG et JpegOptim
- Postfix : résoudre l’erreur “fatal: www-data(33): message file too big”
- Serveur dédié : mise en place de l’IPv6
- WordPress : accorder les bonnes permissions aux fichiers et dossiers avec chown et chmod
- WordPress : héberger les images sur un sous-domaine
- Serveur dédié : ajouter l’authentification SPF, Sender-ID et DKIM à Postfix et Bind9 avec opendkim
- Apache : lorsque le domaine seul (sans WWW) renvoie une erreur 403
- Serveur dédié : sécuriser Apache avec HTTPS (HTTP avec la couche TLS/SSL) en Perfect Forward Secrecy
- Serveur dédié : passer WordPress en HTTPS (TLS/SSL)
- Serveur dédié : configurer Webmin en TLS avec un certificat SSL
- Serveur dédié : configurer Transmission pour accéder au WebUI via TLS-SSL
- Serveur dédié : installer et configurer Varnish 4
- Serveur dédié : passage au mod FastCGI et PHP-FPM avec Apache MPM Worker
- Récupérer un serveur Kimsufi après un plantage de kernel avec le mode rescue OVH
- Serveur dédié : configurer Postfix et Courier pour utiliser TLS-SSL en Perfect Forward Secrecy
- Serveur dédié : retirer Varnish, devenu inutile avec HTTPS
- Serveur dédié : installer la dernière version d’OpenSSL sous Debian
- Serveur dédié : activer l’IP canonique du serveur sous Apache
- Serveur dédié : mise à jour vers PHP 5.6
- MySQL : convertir les tables MyISAM au format InnoDB
- Serveur dédié : optimiser toutes les images GIF avec GIFsicle
- Serveur dédié : migration de MySQL vers MariaDB
- BASH : lister, bloquer et débloquer des adresses IP avec iptables
- Serveur dédié : produire une meilleure réserve d’entropie avec haveged
- Serveur dédié : mettre en place DNSSEC pour sécuriser les DNS du domaine
- Serveur dédié : mise en place du protocole DANE
- 8 règles d’or pour bien déployer DNSSEC et DANE
- Serveur dédié : installer PHP7 FPM avec FastCGI sous Debian
- Serveur dédié : optimiser la couche TCP
- Fail2Ban: protéger Postfix contre les attaques DoS de types AUTH, UNKNOWN et EHLO
- Serveur dédié : mettre à jour Apache pour HTTP/2
- Serveur dédié : ajouter le domaine à la liste HSTS preload
- Serveur dédié : ajouter l’authentification DMARC à Postfix et BIND
- Serveur dédié : à la recherche de l’inode perdue ou comment résoudre le problème “no space left on device”
- Serveur dédié : installer NginX avec support HTTP2 et certificat SSL, PHP, MariaDB sous Debian
Vous avez un projet WordPress ou WooCommerce en tête? Transformez votre vision en réalité avec mon expertise reconnue.
Article mis à jour :
– ajout des paramètres
-appConnTimeout
et-idle-timeout
dans la configuration FastCgi (étape 3).– ajout du fichier
error_log
dans le fichier php.ini de PHP-FPM (étape 4).Tu as pu voir des différences de performances entre MySQL et MariaDB de 4% en faveur de MariaDB, du coup avec PHP-FPM tu vois une vrai différence ?
Difficile à dire : cela me semble un tout petit plus rapide qu’avant mais cela pourrait aussi bien être un effet placebo…
Je me dis que c’est aussi une manière de se tourner vers système de gestion de base de données plus réactif et disposant de davantage de fonctions que MySQL. Il est d’ailleurs de plus en plus proposé sur les distributions.
Le principal boost viendra très probablement de PHP7, qui promet d’excellentes performances à tous niveaux.
mais adebian 7 utilise apache 2.2 , pas 2.4 …???
Bonjour fds,
C’est exact, je viens de modifier l’article pour la dernière version stable de Debian.
Debian 7 possède effectivement Apache 2.2, Debian 8 Apache 2.4
Un super Tutoriel et ça marche avec ubuntu 15.04. Merci beaucoup.
Juste, une petite question: Comment mettre en place plusieurs sites web avec des utilisateurs différents ? (pour sécuriser).
Merci encore
Bonjour,
Il suffit de créer un VirtualHost pour chaque site. Ensuite, je pense qu’il faut utiliser le module Apache 2 ITK MPM.
Article mis à jour:
– ajout des instructions pour PHP7.
– ajout de la configuration pour MPM Worker.
Bonjour, est-ce sans risque de faire cette manip lorsque un ou plusieurs serveurs tournent déjà sur la config existante ? étant relativement noob en la matière, j’ai eu quelques déboires en suivant le tuto sur la maj ver PHP 5.6 et j’ai perdu tout mes serveurs (cela avait littéralement vidé mon dossier /var/www ).Avec cette manip pour php-fpm Cela va t’il les désinstaller aussi ou non ? autre question, aurais-je à réecrire tout mes virtualhost ?
merci d’avance
Bonjour zboob,
Il est recommandé de faire une sauvegarde des fichiers et des fichiers de configuration VirtualHosts avant toute intervention sur un serveur de production qui héberge des sites actifs. Il faut penser à sauvegarder le dossier
/etc/
également.Une fois les sauvegardes faites, il est assez aisé de faire la mise à jour. Au pire, il sera toujours possible de remettre la configuration initiale.
Ps : les VirtualHosts n’auront pas besoin d’être réécrits.