Aller au contenu

PHP : PHP-FPM et serveur web

PHP-FPM (FastCGI Process Manager) exécute le PHP en processus séparés, avec lesquels le serveur web communique par socket. Les exemples utilisent des noms génériques (exemple.com, /var/www/monapp/public, version 8.3 : remplacer par 8.5 sur Ubuntu 26.04).

Fenêtre de terminal
sudo apt install php-fpm
sudo systemctl enable --now php8.3-fpm
ls /run/php/ # php8.3-fpm.sock
sudo php-fpm8.3 -t # teste la configuration

/etc/nginx/sites-available/exemple.com :

server {
listen 80;
server_name exemple.com;
root /var/www/monapp/public;
index index.php;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}
location ~ /\.(?!well-known) {
deny all;
}
}
Fenêtre de terminal
sudo ln -s /etc/nginx/sites-available/exemple.com /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx

try_files redirige les URL vers index.php (application à point d’entrée unique). Voir Nginx : sites virtuels.

exemple.com {
root * /var/www/monapp/public
encode zstd gzip
php_fastcgi unix//run/php/php8.3-fpm.sock
file_server
}

php_fastcgi gère à la fois les fichiers .php, la réécriture vers index.php et les erreurs. Voir Caddy : exemples réutilisables.

Avec PHP-FPM (plutôt que mod_php) :

Fenêtre de terminal
sudo a2enmod proxy_fcgi setenvif
sudo a2enconf php8.3-fpm
sudo a2dismod php8.3 mpm_prefork 2>/dev/null
sudo a2enmod mpm_event
sudo systemctl restart apache2

Le fichier de configuration php8.3-fpm est fourni par le paquet php8.3-fpm. Voir Apache : installation.

Par défaut, PHP-FPM tourne sous l’utilisateur www-data.

Fenêtre de terminal
sudo chown -R deploy:www-data /var/www/monapp
sudo find /var/www/monapp -type d -exec chmod 750 {} +
sudo find /var/www/monapp -type f -exec chmod 640 {} +
sudo chmod -R 770 /var/www/monapp/var # dossiers où PHP écrit (cache, téléversements)

Principe : le code appartient à un utilisateur de déploiement et n’est pas modifiable par www-data ; seuls les dossiers d’écriture le sont.

Isoler chaque site sous son propre utilisateur, /etc/php/8.3/fpm/pool.d/monapp.conf :

[monapp]
user = monapp
group = monapp
listen = /run/php/monapp.sock
listen.owner = www-data
listen.group = www-data
pm = ondemand
pm.max_children = 10
pm.process_idle_timeout = 30s
php_admin_value[open_basedir] = /var/www/monapp:/tmp
php_admin_value[upload_tmp_dir] = /var/www/monapp/tmp
Fenêtre de terminal
sudo adduser --system --group --no-create-home monapp
sudo php-fpm8.3 -t && sudo systemctl reload php8.3-fpm

Le serveur web pointe alors vers /run/php/monapp.sock.

Mode pm Usage
static Nombre fixe de processus : charge élevée et mémoire suffisante
dynamic Variable entre un minimum et un maximum
ondemand Processus créés à la demande : faible trafic, plusieurs petits sites

pm.max_children : environ (mémoire disponible pour PHP) divisée par (mémoire d’un processus, visible avec ps -ylC php-fpm8.3 --sort:rss).

  • Ne pas exposer .env, .git, composer.json : la racine web est le dossier public/, pas la racine du projet.
  • Empêcher l’exécution de PHP dans les dossiers de téléversement.
  • expose_php = Off dans php.ini (voir Configuration).
  • Garder PHP à jour (unattended-upgrades).
Fenêtre de terminal
sudo journalctl -u php8.3-fpm -n 50
sudo tail -f /var/log/php8.3-fpm.log
sudo tail -f /var/log/nginx/error.log
Symptôme Piste
502 Bad Gateway Service arrêté ou mauvais chemin de socket : systemctl status php8.3-fpm, ls /run/php/
connect() to unix:… failed (13: Permission denied) listen.owner / listen.group ne correspondent pas à l’utilisateur du serveur web
Le navigateur propose de télécharger le fichier .php Bloc location ~ \.php$ absent ou php_fastcgi manquant
File not found. root incorrect ou SCRIPT_FILENAME : vérifier le chemin dans le bloc server
Primary script unknown Même cause : chemin du script inexistant
server reached pm.max_children Augmenter pm.max_children si la mémoire le permet

Ubuntu 24.04 et 26.04 : différences à connaître

Section intitulée « Ubuntu 24.04 et 26.04 : différences à connaître »

Mêmes réglages sur les deux versions ; seuls changent le numéro de version dans les noms (php8.3-fpm, php8.5-fpm, socket php8.5-fpm.sock). Utiliser php-fpm sans version dans un script d’installation, et lire le nom du socket avec ls /run/php/.