Si vous avez déjà vu un “Allowed memory size exhausted” côté WordPress alors que votre php -i affiche une mémoire confortable, vous avez rencontré le grand classique : le PHP en ligne de commande et le PHP-FPM du serveur web ne lisent pas le même php.ini. Et derrière, les réglages PHP-FPM (pool, timeouts, OPcache) peuvent transformer un site WordPress 6.9.4 en fusée… ou en générateur de 502.

Le besoin / Le problème serveur

Vous voulez un serveur WordPress rapide et stable, sans “bidouilles” au hasard. Concrètement : uploads fiables, imports qui ne meurent pas à mi-chemin, administration fluide, et pages publiques qui ne partent pas en 504 dès qu’un crawler arrive.

Le problème vient souvent d’un trio :

  • Un php.ini mal ciblé (modifications faites sur le mauvais fichier, ou sur le PHP CLI au lieu de PHP-FPM).
  • Un pool PHP-FPM mal dimensionné (trop de processus = RAM explosée, pas assez = latence, 502/504).
  • Un OPcache sous-configuré (ou à l’inverse “trop agressif” avec des déploiements qui ne se reflètent pas).

À la fin, vous saurez : identifier les bons fichiers de conf, appliquer des réglages adaptés à WordPress 6.9.4 (PHP 8.1+), dimensionner PHP-FPM selon votre RAM, activer OPcache proprement, et vérifier le tout par commandes.

Résumé rapide

  • Ne touchez pas au hasard : identifiez d’abord le php.ini réellement chargé par PHP-FPM (pas celui du CLI).
  • Pour WordPress : memory_limit réaliste (256M/512M), max_execution_time cohérent, post_max_size/upload_max_filesize alignés.
  • PHP-FPM : dimensionnez pm.max_children avec une mesure (taille RSS d’un worker), pas à l’instinct.
  • OPcache : activez-le, augmentez opcache.memory_consumption, et fixez opcache.max_accelerated_files pour WordPress + plugins.
  • JIT : rarement utile pour WordPress ; si vous l’activez, faites-le en connaissance de cause et benchmarkez.
  • Vérifiez avec curl, logs PHP-FPM/Nginx/Apache, et un endpoint WordPress minimal.

Avant de commencer (prérequis)

Accès nécessaires :

  • SSH avec un utilisateur sudo (ou root).
  • WP-CLI sur le serveur (ou via un conteneur/VM).
  • Accès aux logs (Nginx/Apache + PHP-FPM).
  • Accès à MySQL/MariaDB (lecture au minimum) si vous voulez corréler charge PHP et lenteurs SQL.

Sauvegarde obligatoire (ne testez pas ça “en prod” sans filet). Je vois encore des sites cassés parce qu’un php.ini contient une virgule à la place d’un point… et PHP-FPM refuse de redémarrer.

# Sauvegardes rapides des configs (adaptez les chemins)
sudo mkdir -p /root/backup-conf-phpfpm-$(date +%F)

# PHP (FPM + CLI)
sudo cp -a /etc/php /root/backup-conf-phpfpm-$(date +%F)/ 2>/dev/null || true

# Nginx / Apache
sudo cp -a /etc/nginx /root/backup-conf-phpfpm-$(date +%F)/ 2>/dev/null || true
sudo cp -a /etc/apache2 /root/backup-conf-phpfpm-$(date +%F)/ 2>/dev/null || true

# PHP-FPM (selon distro)
sudo cp -a /etc/php-fpm.d /root/backup-conf-phpfpm-$(date +%F)/ 2>/dev/null || true
sudo cp -a /etc/php/*/fpm /root/backup-conf-phpfpm-$(date +%F)/ 2>/dev/null || true

Versions cibles (avril 2026) :

  • WordPress 6.9.4
  • PHP 8.1+ (8.2/8.3/8.4 très courants en prod)
  • Serveur web : Nginx ou Apache, avec PHP-FPM.

Références officielles utiles :

Étape 1 : Cartographier votre PHP (CLI) vs PHP-FPM (web) et trouver le bon php.ini

Le piège numéro 1 : modifier /etc/php/8.x/cli/php.ini (parce que c’est celui que vous trouvez) et ne rien voir changer dans WordPress. Normal : WordPress tourne via PHP-FPM, donc lit typiquement /etc/php/8.x/fpm/php.ini (Debian/Ubuntu) ou /etc/php.ini + /etc/php-fpm.d/*.conf (RHEL/Alma/Rocky).

1) Identifier la version PHP réellement servie par le web

# Réponse HTTP et en-têtes (utile pour voir si un cache/proxy masque les changements)
curl -I https://votre-domaine.tld/

Ensuite, l’approche propre consiste à exposer temporairement un endpoint qui affiche la conf PHP-FPM. Je préfère éviter phpinfo() en public (c’est une fuite d’infos). Faites-le en local, protégé, puis supprimez.

# Créez un fichier temporaire (protégé par IP ou Basic Auth côté serveur web)
# Exemple : /var/www/html/_diag/phpinfo.php
sudo tee /var/www/html/_diag/phpinfo.php >/dev/null <<'PHP'
<?php
// Diagnostic temporaire : supprimez ce fichier après usage.
phpinfo();
PHP

Si vous ne pouvez pas exposer un fichier web, vous pouvez aussi lire la conf FPM via systemd et les fichiers de service (selon distro), mais le plus fiable reste la sortie phpinfo() côté FPM.

2) Vérifier les chemins de php.ini côté CLI et côté FPM

# Côté CLI
php --ini

# Lister les services PHP-FPM (noms variables)
systemctl list-units --type=service | grep -E 'php.*fpm' || true

# Statut du service (exemples)
sudo systemctl status php8.3-fpm --no-pager 2>/dev/null || true
sudo systemctl status php-fpm --no-pager 2>/dev/null || true

Dans phpinfo() (côté web), cherchez :

  • Loaded Configuration File (le php.ini réellement chargé)
  • Scan this dir for additional .ini files (dossier des conf.d)

3) Anti-pattern : changer la mémoire dans wp-config.php “pour corriger”

J’ai souvent vu des sites où on empile :

  • define('WP_MEMORY_LIMIT', '512M'); dans wp-config.php
  • un ini_set('memory_limit', ...) dans un plugin
  • et un memory_limit serveur à 128M

Résultat : confusion, et parfois WordPress ne peut pas dépasser la limite serveur. La bonne pratique : fixez d’abord des limites cohérentes au niveau php.ini (FPM), puis ajustez WordPress si nécessaire.

Étape 2 : Régler php.ini pour WordPress 6.9.4 (valeurs réalistes et justifiées)

Les valeurs ci-dessous sont des “bons défauts” pour un WordPress moderne (6.9.4) sur un serveur standard (2 à 8 vCPU, 4 à 16 Go RAM). Si vous êtes sur un micro-serveur 1 Go, on dimensionne autrement, surtout côté PHP-FPM.

Réglages recommandés (FPM) pour un site WordPress typique

Éditez le php.ini chargé par FPM (ex : /etc/php/8.3/fpm/php.ini).

# Exemple Debian/Ubuntu
sudo nano /etc/php/8.3/fpm/php.ini

Directives clés :

  • memory_limit : 256M est un plancher confortable. 512M si vous faites beaucoup d’imports (WooCommerce, LMS, gros builders) ou si vous avez des plugins lourds.
  • max_execution_time : 120s est souvent un bon compromis. Pour des imports, 300s peut être nécessaire, mais attention aux timeouts Nginx/Apache en face.
  • max_input_vars : avec Divi 5 / Avada / Elementor et des pages complexes, 5000 à 10000 évite des formulaires tronqués.
  • post_max_size et upload_max_filesize : alignez-les (post ≥ upload). Si vous mettez upload à 128M et post à 64M, vous aurez des uploads qui échouent “sans raison”.

Exemple de bloc de réglages (à adapter)

# Recherche rapide des valeurs actuelles
php -r 'echo "CLI memory_limit=" . ini_get("memory_limit") . PHP_EOL;'
sudo -u www-data php -r 'echo "Même commande, autre user (CLI): " . ini_get("memory_limit") . PHP_EOL;' 2>/dev/null || true

Ajoutez/modifiez dans php.ini (FPM) :

# Ces lignes sont des directives php.ini (pas du PHP)
# Ouvrez /etc/php/8.x/fpm/php.ini et ajustez :

# Mémoire : WordPress + plugins modernes
memory_limit = 256M

# Uploads et POST : évitez les incohérences
upload_max_filesize = 128M
post_max_size = 128M

# Exécution : imports / sauvegardes / régénérations
max_execution_time = 120
max_input_time = 120

# Formulaires énormes (builders, méga-menus)
max_input_vars = 5000

# Sessions : WordPress core n'en dépend pas, mais certains plugins oui
session.gc_maxlifetime = 1440

# Erreurs : en prod, pas d'affichage (log uniquement)
display_errors = Off
log_errors = On
error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT

Note : E_DEPRECATED peut être utile en staging pour repérer des plugins/thèmes qui traînent, mais en prod j’évite d’inonder les logs, surtout si vous avez des extensions verbeuses.

Réglages “souvent demandés” mais à manipuler avec prudence

  • allow_url_fopen : beaucoup de plugins l’utilisent (téléchargements, API). Le désactiver peut casser des fonctionnalités. Si vous voulez durcir, faites-le par politique réseau (egress) plutôt que par cette directive.
  • disable_functions : tentant, mais peut casser WP-CLI, des plugins de sauvegarde, ou Imagick/GD selon fonctions. Si vous le faites, testez en staging.
  • open_basedir : peut améliorer l’isolation, mais casse régulièrement des plugins (accès à /tmp, polices, caches). Préférez une isolation par utilisateur/pool + permissions.

Étape 3 : Optimiser PHP-FPM (pool, process manager, timeouts, logs)

Le réglage qui change vraiment la stabilité : dimensionner le pool. Trop de workers et vous swappez (site lent, puis mort). Pas assez et vous faites la queue (latence, timeouts).

1) Localiser la conf du pool

Selon la distro :

  • Debian/Ubuntu : /etc/php/8.x/fpm/pool.d/www.conf
  • RHEL-like : /etc/php-fpm.d/www.conf
# Trouver les fichiers pool
sudo find /etc -maxdepth 4 -type f -name "www.conf" -o -name "*.conf" | grep -E 'fpm|pool' | head -n 50

2) Choisir pm = dynamic vs ondemand

Pour WordPress, je choisis souvent :

  • pm = dynamic sur serveur “stable” (trafic régulier), pour éviter les spikes de latence.
  • pm = ondemand sur petit serveur (faible trafic, RAM limitée), pour économiser la mémoire au repos.

J’ai souvent croisé des 502 sur des VPS 2 Go avec pm.max_children à 50 “parce qu’un tuto l’a dit”. C’est le chemin le plus court vers l’OOM killer.

3) Dimensionner pm.max_children avec une mesure

Mesurez la consommation d’un worker PHP-FPM en charge “réaliste” (admin + front). Méthode simple :

# 1) Générer un peu de trafic (à défaut, rechargez quelques pages + admin)
# 2) Inspecter les processus php-fpm

ps -ylC php-fpm --sort:rss | awk 'NR==1{print} NR>1{sum+=$8; n++; if(n<=10) print} END{print "RSS total(kB)=",sum," sur ",n,"processus"}'

# Alternative si le nom du binaire diffère
ps aux | grep -E 'php-fpm: pool' | grep -v grep | awk '{print $2}' | head

Règle pratique :

  • RAM disponible pour PHP = RAM totale – (MySQL + OS + cache + marge).
  • pm.max_children ≈ RAM_PHP / RSS_moyen_d_un_worker.

4) Exemple de pool WordPress “sain” (dynamic)

Éditez www.conf (ou créez un pool dédié par site si multi-sites).

sudo nano /etc/php/8.3/fpm/pool.d/www.conf
; Réglages PHP-FPM pour WordPress (exemple)
; Les commentaires sont en français, gardez-les : vous vous remercierez dans 6 mois.

[www]
user = www-data
group = www-data

; Écoute en socket (souvent plus rapide/plus simple que TCP en local)
listen = /run/php/php8.3-fpm.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660

; Mode de gestion des processus
pm = dynamic

; À dimensionner selon la RAM. Exemple : petit serveur 4 Go, site moyen.
pm.max_children = 20

; Processus au démarrage et seuils
pm.start_servers = 4
pm.min_spare_servers = 4
pm.max_spare_servers = 10

; Recyclage pour limiter les fuites mémoire côté extensions
pm.max_requests = 500

; Timeouts : évite les workers bloqués indéfiniment
request_terminate_timeout = 120s

; Logs lents : indispensable pour diagnostiquer un plugin qui plombe tout
request_slowlog_timeout = 5s
slowlog = /var/log/php8.3-fpm/www-slow.log

; Status/ping (optionnel) : utile pour monitoring, à protéger côté Nginx/Apache
pm.status_path = /fpm-status
ping.path = /fpm-ping
ping.response = pong

Si vous utilisez Elementor, Divi 5 ou Avada, vous verrez souvent des pics de CPU lors de l’édition (chargement de previews, AJAX). Le slowlog est votre meilleur ami : il vous dira quel script PHP dépasse le seuil.

5) Redémarrer proprement

# Test de syntaxe (selon version, pas toujours disponible)
php-fpm8.3 -t 2>/dev/null || true
php-fpm -t 2>/dev/null || true

# Redémarrage
sudo systemctl restart php8.3-fpm 2>/dev/null || sudo systemctl restart php-fpm

# Vérifier l'état
sudo systemctl --no-pager --full status php8.3-fpm 2>/dev/null || sudo systemctl --no-pager --full status php-fpm

Étape 4 : OPcache (et JIT) : performance sans se tirer une balle dans le pied

Sur WordPress, OPcache apporte presque toujours un gain mesurable. Le JIT, beaucoup moins : WordPress est majoritairement I/O (DB, réseau) et “framework-like”, pas du calcul intensif. J’ai vu des JIT activés “par principe” qui compliquent le debug sans bénéfice net.

Doc officielle :

Réglages OPcache recommandés (PHP-FPM)

Sur Debian/Ubuntu, c’est souvent dans /etc/php/8.x/fpm/conf.d/10-opcache.ini ou /etc/php/8.x/mods-available/opcache.ini.

# Trouver le fichier opcache
php --ini | sed -n '1,120p'
sudo find /etc/php -type f -name "*opcache*.ini" 2>/dev/null | head -n 50

Exemple de configuration :

; OPcache pour WordPress (exemple)
opcache.enable=1
opcache.enable_cli=0

; Mémoire OPcache : 128M pour petit site, 256M si beaucoup de plugins/builders
opcache.memory_consumption=256

; Buffer des chaînes internées (utile avec beaucoup de code PHP)
opcache.interned_strings_buffer=16

; WordPress + plugins + vendor : montez ce chiffre pour éviter l'éviction
opcache.max_accelerated_files=60000

; Revalidation : en prod, vous pouvez garder 2s pour éviter les "code pas à jour"
; Si vous déployez via CI, vous pouvez aussi purger/reload PHP-FPM à chaque déploiement.
opcache.validate_timestamps=1
opcache.revalidate_freq=2

; Évite certains problèmes de fragmentation
opcache.max_wasted_percentage=10

JIT : quand l’activer (rarement) et comment

Si vous avez un site WordPress qui fait du traitement d’image/vidéo côté PHP (déjà atypique) ou des calculs lourds, benchmarkez. Sinon, laissez JIT désactivé.

; JIT (optionnel) - à activer uniquement après tests
opcache.jit=0
opcache.jit_buffer_size=0

Si vous activez :

; Exemple (à benchmarker)
opcache.jit=tracing
opcache.jit_buffer_size=64M

Étape 5 : Réduire les risques (fonctions dangereuses, uploads, timeouts) sans casser WordPress

Le durcissement “à la hache” casse WordPress. Le durcissement utile se fait par couches : PHP (erreurs, exposition), FPM (isolation/pool), serveur web (headers, accès), et OS (permissions, egress).

1) Exposition minimale côté PHP

; Dans php.ini (FPM)
expose_php = Off
display_errors = Off
log_errors = On

2) Limiter la taille des uploads sans piéger l’éditeur

Fixez un plafond cohérent (ex : 128M) et gardez post_max_sizeupload_max_filesize. Pour des médias lourds (podcasts/vidéos), préférez un stockage objet (S3-compatible) plutôt que des uploads géants via PHP.

3) Timeouts cohérents entre PHP-FPM et Nginx/Apache

Un classique : max_execution_time=300 mais Nginx coupe à 60s. Vous “augmentez PHP”, ça ne change rien. Il faut aligner les deux.

  • PHP : max_execution_time et/ou request_terminate_timeout
  • Nginx : fastcgi_read_timeout
  • Apache (proxy_fcgi) : timeouts côté proxy/module (selon conf)

Fichiers de configuration complets

php.ini (exemple complet minimal orienté WordPress / PHP-FPM)

Ce fichier n’est pas un php.ini “par défaut” complet de distribution : c’est un exemple prêt à copier-coller pour un pool WordPress, avec les directives qui comptent. Gardez les autres valeurs par défaut de votre distro.

; =========================
; php.ini (extrait complet utile WordPress)
; Cible : PHP 8.1+ / WordPress 6.9.4
; =========================

[PHP]
engine = On
short_open_tag = Off
precision = 14
output_buffering = 4096
zlib.output_compression = Off
implicit_flush = Off

; Sécurité / exposition
expose_php = Off

; Ressources
max_execution_time = 120
max_input_time = 120
memory_limit = 256M

; Uploads
file_uploads = On
upload_max_filesize = 128M
post_max_size = 128M
max_file_uploads = 20

; Formulaires (builders)
max_input_vars = 5000

; Erreurs (prod)
display_errors = Off
display_startup_errors = Off
log_errors = On
error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT

; Chemin de logs : préférez un log dédié par pool FPM si possible
; error_log = /var/log/php/php-error.log

[Date]
date.timezone = Europe/Paris

[Session]
session.use_strict_mode = 1
session.cookie_httponly = 1
session.cookie_samesite = Lax

[opcache]
opcache.enable=1
opcache.enable_cli=0
opcache.memory_consumption=256
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=60000
opcache.validate_timestamps=1
opcache.revalidate_freq=2
opcache.max_wasted_percentage=10
opcache.jit=0
opcache.jit_buffer_size=0

PHP-FPM pool (www.conf) complet (exemple)

; =========================
; /etc/php/8.x/fpm/pool.d/www.conf (exemple)
; =========================
[www]

; Utilisateur du pool (adaptez si vous isolez par site)
user = www-data
group = www-data

listen = /run/php/php8.3-fpm.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660

; Choix : dynamic pour trafic régulier
pm = dynamic

; Dimensionnement : adaptez selon la RAM et le RSS mesuré
pm.max_children = 20
pm.start_servers = 4
pm.min_spare_servers = 4
pm.max_spare_servers = 10

; Recyclage pour limiter la dérive mémoire
pm.max_requests = 500

; Timeouts
request_terminate_timeout = 120s

; Diagnostic perf
request_slowlog_timeout = 5s
slowlog = /var/log/php8.3-fpm/www-slow.log

; Logs d'accès FPM (optionnel, utile en debug puis à couper)
; access.log = /var/log/php8.3-fpm/www-access.log
; access.format = "%R - %u %t "%m %r" %s %f %{mili}dms %{kilo}Mkb %C%%"

; Endpoints de statut (à protéger côté serveur web)
pm.status_path = /fpm-status
ping.path = /fpm-ping
ping.response = pong

; Variables d'environnement (évitez de mettre des secrets ici)
clear_env = yes

nginx.conf (server block) complet avec PHP-FPM + timeouts alignés

Exemple minimal. Adaptez les chemins (root, socket FPM) et ajoutez votre TLS/HTTP2/HTTP3 selon votre stack.

server {
    listen 80;
    server_name votre-domaine.tld;
    root /var/www/votre-site/public;

    index index.php index.html;

    # WordPress : permaliens
    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    # PHP-FPM
    location ~ .php$ {
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

        fastcgi_pass unix:/run/php/php8.3-fpm.sock;

        # Timeouts : alignez avec PHP (max_execution_time / request_terminate_timeout)
        fastcgi_connect_timeout 10s;
        fastcgi_send_timeout 120s;
        fastcgi_read_timeout 120s;

        # Buffers : évite certains "upstream sent too big header"
        fastcgi_buffer_size 32k;
        fastcgi_buffers 16 16k;
    }

    # Bloquer l'accès aux fichiers sensibles
    location ~* /(wp-config.php|readme.html|license.txt) {
        deny all;
    }

    # Protéger endpoints FPM (si vous les exposez)
    location = /fpm-status { deny all; }
    location = /fpm-ping { deny all; }
}

.htaccess (Apache) complet minimal (si vous êtes sur Apache + PHP-FPM)

Si vous utilisez Apache, évitez de compter sur php_value dans .htaccess avec PHP-FPM : ça ne marche pas comme avec mod_php. Réglez PHP dans php.ini / pool FPM.

# .htaccess (WordPress) - exemple minimal
# Les règles de permaliens sont normalement gérées par WordPress.
# N'ajoutez pas de directives php_value ici si vous êtes sur PHP-FPM.

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

wp-config.php (extrait) : limites WordPress cohérentes avec le serveur

Ne mettez pas ça “pour compenser” un serveur trop strict. Utilisez-le pour aligner WordPress sur vos choix serveur, surtout en admin.

<?php
// wp-config.php (extrait) - WordPress 6.9.4
// Objectif : éviter les divergences entre WordPress et php.ini.

// Mémoire pour le front (ne dépasse pas memory_limit serveur)
define('WP_MEMORY_LIMIT', '256M');

// Mémoire pour l'admin (builders, import/export)
define('WP_MAX_MEMORY_LIMIT', '512M');

// Debug : ne pas afficher en prod
define('WP_DEBUG', false);
define('WP_DEBUG_DISPLAY', false);

// Si vous loggez, assurez-vous que wp-content/debug.log est protégé et non exposé
define('WP_DEBUG_LOG', false);

Vérification

Après chaque changement : rechargez PHP-FPM et validez que WordPress voit les nouvelles limites. Je préfère des tests “bêtes” mais fiables, plutôt qu’un “ça a l’air bon”.

1) Vérifier que PHP-FPM redémarre et écoute

sudo systemctl restart php8.3-fpm 2>/dev/null || sudo systemctl restart php-fpm
sudo systemctl is-active php8.3-fpm 2>/dev/null || sudo systemctl is-active php-fpm

# Vérifier la socket
ls -l /run/php/ | grep fpm || true

2) Vérifier côté HTTP (pas côté CLI)

# Endpoint de diagnostic (si vous avez créé phpinfo.php)
curl -sS https://votre-domaine.tld/_diag/phpinfo.php | grep -E "Loaded Configuration File|memory_limit|opcache.enable" | head -n 50

3) Vérifier WordPress via WP-CLI

# Vérifier la santé WordPress
cd /var/www/votre-site/public
wp core version
wp plugin status --skip-themes

# Vérifier les permaliens (utile après migrations, pas directement lié à PHP, mais souvent oublié)
wp rewrite flush --hard

4) Vérifier OPcache

Sans script dédié, vous pouvez au minimum vérifier que l’extension est chargée côté FPM via phpinfo(). Pour un check plus “code”, créez temporairement un endpoint protégé :

sudo tee /var/www/html/_diag/opcache.php >/dev/null <<'PHP'
<?php
// Diagnostic temporaire : supprimez ce fichier après usage.
header('Content-Type: application/json; charset=utf-8');

if (!function_exists('opcache_get_status')) {
    echo json_encode(['opcache' => 'absent'], JSON_PRETTY_PRINT);
    exit;
}

$status = opcache_get_status(false);
echo json_encode([
    'opcache_enabled' => (bool)($status['opcache_enabled'] ?? false),
    'cache_full'      => (bool)($status['cache_full'] ?? false),
    'memory_usage'    => $status['memory_usage'] ?? null,
    'interned'        => $status['interned_strings_usage'] ?? null,
], JSON_PRETTY_PRINT);
PHP
curl -sS https://votre-domaine.tld/_diag/opcache.php | head -n 80

Si ça ne marche pas

Quand ça casse après un changement PHP/FPM, c’est rarement “WordPress”. C’est : un service qui ne redémarre pas, une socket non accessible, ou un timeout en cascade.

Checklist diagnostic (par étapes)

1) PHP-FPM ne redémarre pas

sudo systemctl restart php8.3-fpm 2>/dev/null || sudo systemctl restart php-fpm
sudo journalctl -u php8.3-fpm -n 200 --no-pager 2>/dev/null || sudo journalctl -u php-fpm -n 200 --no-pager

Causes fréquentes :

  • Directive inconnue (copie d’un vieux tuto) ou faute de frappe dans php.ini.
  • Chemin de slowlog non accessible (permissions).
  • Socket déjà utilisée (mauvais listen).

2) 502 Bad Gateway (Nginx) / 503 (Apache proxy) après redémarrage

# Logs Nginx
sudo tail -n 200 /var/log/nginx/error.log 2>/dev/null || true

# Vérifier que la socket existe et que Nginx peut l'ouvrir
sudo ls -l /run/php/php8.3-fpm.sock 2>/dev/null || true

# Vérifier les erreurs PHP-FPM
sudo tail -n 200 /var/log/php8.3-fpm.log 2>/dev/null || true
sudo tail -n 200 /var/log/php-fpm/error.log 2>/dev/null || true

3) Timeouts (504) sur certaines actions admin (imports, builder, sauvegardes)

# Cherchez des "upstream timed out" côté Nginx
sudo grep -R "upstream timed out" -n /var/log/nginx 2>/dev/null | tail -n 20

# Slowlog PHP-FPM (si activé)
sudo tail -n 200 /var/log/php8.3-fpm/www-slow.log 2>/dev/null || true

Tableau de diagnostic (symptômes réalistes)

Symptôme Cause probable Vérification Solution
WordPress affiche toujours l’ancienne limite mémoire Vous avez modifié le php.ini du CLI au lieu de celui de FPM php --ini vs “Loaded Configuration File” dans phpinfo() Modifier /etc/php/8.x/fpm/php.ini (ou conf FPM équivalente), redémarrer FPM
502 Bad Gateway après redémarrage Socket FPM absente ou permissions incorrectes ls -l /run/php/*.sock + tail logs Nginx Corriger listen/listen.mode et redémarrer PHP-FPM puis Nginx
504 sur import/mise à jour Timeout Nginx/Apache plus bas que PHP Logs “upstream timed out” + valeurs fastcgi_read_timeout Aligner timeouts (web + FPM) ou passer l’opération en tâche asynchrone
Le serveur swap et devient très lent pm.max_children trop élevé free -h, vmstat 1, OOM dans journalctl Réduire pm.max_children, activer cache objet, optimiser plugins
Pages parfois “pas à jour” après déploiement OPcache revalidation trop faible ou déploiement incomplet Comparer fichiers, vérifier opcache.validate_timestamps Garder validate_timestamps=1 + revalidate_freq=2, ou reload FPM au déploiement

Pièges et erreurs courantes

Erreur Cause Solution
Copier une conf trouvée en ligne “telle quelle” Différences distro/version PHP, directives obsolètes Vérifier sur PHP.net – liste des directives et tester php-fpm -t
Modifier le mauvais fichier Confusion CLI vs FPM Utiliser phpinfo() protégé pour connaître “Loaded Configuration File”
Augmenter pm.max_children pour “accélérer” Plus de workers ≠ plus rapide si la RAM manque Mesurer RSS moyen d’un worker, recalculer, surveiller swap/OOM
Activer display_errors=On en prod Debug rapide… qui fuit des infos sensibles Loguer côté serveur, afficher seulement en staging
Oublier de redémarrer PHP-FPM Les changements ne s’appliquent pas systemctl restart php*-fpm + re-test HTTP
Mettre upload_max_filesize > post_max_size Uploads qui échouent silencieusement Aligner : post_max_sizeupload_max_filesize
Tester directement sur production sans sauvegarde Un redémarrage raté = site down Staging + sauvegarde + fenêtre de maintenance
Snippet WordPress “ancien” qui force la mémoire ini_set ignoré / limite serveur plus basse Fixer au niveau php.ini/pool, garder wp-config cohérent

Sécurité serveur

Quelques mesures directement liées à PHP.ini / PHP-FPM, sans casser WordPress :

  • Ne laissez jamais un phpinfo() accessible : fuite de modules, chemins, variables, parfois headers. Supprimez les endpoints /_diag après vérif.
  • Isoler par pool et par utilisateur si vous hébergez plusieurs sites : un pool FPM par vhost limite l’impact d’un site compromis (permissions, sockets, logs).
  • Désactiver l’exécution PHP dans wp-content/uploads côté serveur web (Nginx/Apache). Beaucoup d’infections passent par un upload de fichier .php.
  • Logs : centralisez et protégez. Un log accessible en web (mauvaise conf) est une fuite d’infos.
  • Limiter l’exposition de endpoints : /fpm-status et /fpm-ping doivent être deny all ou restreints par IP/VPN.

Pour les recommandations WordPress côté serveur (hardening), la base officielle reste :

Ressources

FAQ

Quelle valeur de memory_limit choisir pour WordPress 6.9.4 ?

256M couvre la majorité des sites. Passez à 512M si vous utilisez des builders (Divi 5/Elementor/Avada) avec des pages lourdes, WooCommerce avec beaucoup d’extensions, ou des imports fréquents. Si vous montez à 512M, dimensionnez PHP-FPM en conséquence (moins de workers).

Pourquoi php -i ne reflète pas ce que WordPress utilise ?

Parce que php -i interroge le PHP CLI. WordPress tourne via PHP-FPM derrière Nginx/Apache, avec un autre SAPI et souvent un autre php.ini. Utilisez “Loaded Configuration File” dans phpinfo() côté web.

Dois-je activer OPcache sur un serveur WordPress ?

Oui, quasiment toujours. C’est un des gains perf les plus simples. Surveillez juste la taille (opcache.memory_consumption) et le nombre de fichiers (opcache.max_accelerated_files) pour éviter l’éviction.

Le JIT améliore-t-il WordPress ?

Rarement de façon significative. WordPress passe beaucoup de temps en I/O (DB, réseau) et en templates. Activez JIT uniquement si vous avez benchmarké sur votre charge réelle.

Que fait pm.max_requests dans PHP-FPM ?

Ça recycle un worker après N requêtes. C’est utile pour limiter l’impact de fuites mémoire dans des extensions PHP ou des plugins. Valeurs courantes : 300 à 1000. Plus bas = plus de churn, plus haut = plus de dérive possible.

Dynamic ou ondemand pour un blog WordPress ?

dynamic si vous avez du trafic régulier et assez de RAM : latence plus stable. ondemand si vous êtes sur un petit VPS et que vous voulez économiser la mémoire au repos, au prix d’un petit coût au “réveil”.

Pourquoi j’ai des 504 uniquement quand j’édite avec Elementor/Divi ?

Les builders déclenchent beaucoup de requêtes AJAX et des rendus lourds. Souvent vous avez un timeout Nginx (fastcgi_read_timeout) trop bas, ou un pm.max_children trop faible qui crée une file d’attente. Activez le slowlog et regardez ce qui dépasse 5s.

Puis-je régler PHP via .htaccess ?

Avec PHP-FPM, généralement non. Les directives php_value et php_flag s’appliquent surtout avec mod_php. Réglez dans php.ini / pool FPM.

Dois-je augmenter max_input_vars à 10000 ?

Si vous avez des pages très complexes (builders, gros formulaires, méga-menus), oui, ça évite des champs tronqués. Ne montez pas “pour rien” : ça augmente le travail de parsing sur des requêtes énormes.

Comment éviter les “code pas à jour” après un déploiement avec OPcache ?

Gardez opcache.validate_timestamps=1 et opcache.revalidate_freq=2 (ou similaire). Si vous faites du CI/CD, une approche robuste est de reloader PHP-FPM à la fin du déploiement (en fenêtre maîtrisée), plutôt que de mettre revalidate_freq=0 partout.

Qu’est-ce qui casse le plus souvent PHP-FPM après un changement ?

Une faute de frappe dans php.ini ou www.conf, un chemin de log non accessible, ou une directive copiée d’un ancien tutoriel (incompatible avec votre version PHP 8.1+). D’où la routine : sauvegarde, modification, php-fpm -t si dispo, redémarrage, puis journalctl.