« Tout a planté après une mise à jour » : playbook de récupération WordPress en 30 minutes

Cet article vous a aidé ?

Vous avez mis à jour WordPress (ou un plugin, ou PHP), avez rafraîchi la page, et votre site ressemble à une scène de crime. Écran blanc. 500. « Briefly unavailable for scheduled maintenance. » Paiement en panne. Le PDG vous envoie des SMS comme si vous aviez débranché Internet vous-même.

Ceci est un playbook de récupération en production écrit pour les personnes qui exploitent de vrais systèmes : vous voulez un diagnostic rapide, un rollback sûr et le moins de super-héros possible. Vous n’avez pas besoin de folklore. Vous avez besoin d’un chronomètre, des journaux et d’un plan.

La règle des 30 minutes : le triage bat la perfection

Dans les 30 premières minutes, votre seul travail est de restaurer le service en toute sécurité, pas de résoudre WordPress comme un concept philosophique. Cela signifie effectuer des changements rapides et réversibles, prendre des notes et résister à la tentation de « juste ajuster une chose de plus ».

Pensez comme un SRE : choisissez l’intervention la plus petite qui restaure la disponibilité tout en préservant les preuves. Votre futur vous remerciera lors du post-incident quand vous relirez les notes et ne devinerez pas laquelle des huit « petites modifications » a réellement résolu le problème.

Priorités opérationnelles (dans l’ordre)

  1. Arrêter l’hémorragie : restaurer une version fonctionnelle (même dégradée temporairement, par exemple en désactivant un plugin).
  2. Confirmer ce qui est cassé : erreurs HTTP, fatales PHP, connectivité BDD, erreurs de permissions, épuisement de ressources.
  3. Stabiliser : supprimer le déclencheur, vérifier les caches, confirmer les jobs en arrière-plan.
  4. Ce n’est qu’ensuite que vous poursuivez la cause racine et planifiez une correction propre.

Une citation à garder sur un post-it : Idée paraphrasée : « L’espoir n’est pas une stratégie. » — couramment attribuée dans les cercles d’ingénierie à des praticiens comme Gene Kranz ; l’idée reste utile.

Blague #1 : Les mises à jour sont comme des parachutes : si vous ne les testez qu’après avoir sauté, vous allez apprendre beaucoup, très vite.

Playbook de diagnostic rapide (premiers/deuxièmes/troisièmes contrôles)

Ceci est le chemin le plus rapide vers le goulet d’étranglement. Ne faites pas de freestyle. Suivez la séquence pour ne pas perdre 20 minutes dans la mauvaise couche.

Premier : quel est l’échec côté utilisateur ?

  • 503 « mode maintenance » ou message « Briefly unavailable » : probablement le fichier .maintenance coincé, ou une mise à jour avortée.
  • 500 / 502 / 504 : problème web server ↔ PHP-FPM, fatal PHP, timeout en amont, épuisement de ressources.
  • « Error establishing a database connection » : identifiants BDD, BDD down, socket/hôte incorrect, trop de connexions.
  • Écran blanc : fatal PHP avec affichage désactivé, ou fatal thème/plugin dès l’amorçage.
  • Le site charge mais est lent : invalidation de cache, options autoloaded volumineuses, mismatch cache objet, requêtes BDD lentes.

Deuxième : vérifiez les journaux où est la vérité

  1. Journal d’erreurs du serveur web (Nginx/Apache).
  2. Journal PHP-FPM (ou journal systemd pour php-fpm).
  3. Journal de débogage WordPress (si activé).
  4. Journaux / statut de la base de données (si symptômes BDD).

Troisième : faites le rollback le plus petit et sûr

  • Désactivez les plugin(s) les plus récents ou changez de thème.
  • Revenez sur la release de code (symlink ou déploiement git) si disponible.
  • Restaurer depuis une sauvegarde uniquement si rollback impossible ou si le schéma BDD a changé et ne peut pas être concilié.

Raccourci de décision

Si vous ne pouvez pas identifier la couche en échec en 5 minutes, arrêtez de cliquer et commencez à capturer :

  • Codes HTTP actuels pour / et /wp-admin/.
  • Les 50 dernières lignes des journaux d’erreur web + PHP.
  • Les changements de fichiers récents (mtime) dans wp-content.

Ce que signifie généralement « planté après une mise à jour »

1) Mise à jour du core WordPress partiellement appliquée

Une mise à jour du core interrompue (permissions, disque plein, timeout) peut laisser des versions mélangées. Symptômes : erreurs fatales dans des fichiers core, fichiers manquants, comportement aléatoire et le classique verrou « mode maintenance ».

2) Une mise à jour de plugin a introduit une erreur fatale

Le cas le plus fréquent. Un plugin suppose une version PHP, une fonction ou un autre plugin présent. Ou il contient une faute de frappe qui n’a jamais été détectée par l’intégration continue. Symptômes : écran blanc, 500, erreurs fatales référant un chemin de plugin.

3) Mise à jour du thème ou code de thème personnalisé incompatible

Même scénario que pour les plugins, avec en plus le piquant du code functions.php écrit en 2017 et testé pour la dernière fois sur PHP 7.4.

4) La version de PHP a changé sous vos pieds

Mises à jour de l’OS, upgrades du panneau ou un « changement mineur » d’image peuvent faire monter PHP. Symptômes : fatales comme « Call to undefined function », warnings dépréciés devenant fatales (selon la config), ou extensions manquantes (mysqli, intl, imagick).

5) Mismatch cache / cache objet

Les plugins d’object cache Redis/Memcached peuvent casser quand le backend change, le plugin change, ou que les formats de sérialisation évoluent. Symptômes : l’administration fonctionne mais le front échoue, boucles de redirection étranges, erreurs intermittentes qui disparaissent en vidant le cache.

6) Migrations de base de données et dérive de schéma

Certains plugins exécutent des migrations lors de la mise à jour. Si elles échouent à mi-chemin, vous obtenez des écrans admin cassés, des tables manquantes ou des requêtes longues qui écrasent le site.

7) Le mensonge « tout est OK » : en réalité stockage ou permissions

Les mises à jour écrivent des fichiers. Les écritures nécessitent de l’espace, un propriétaire/groupe correct et des options de montage sensées. Si votre disque est plein ou les permissions incorrectes, vous obtenez des mises à jour partielles, des échecs répétés et un site qui semble hanté.

Tâches de récupération pratiques (commandes, sorties, décisions)

Ces tâches sont conçues pour être exécutées dans l’ordre. Chacune inclut : commande, sortie réaliste, ce que cela signifie et la décision à prendre.

Hypothèses : hôte Linux, Nginx ou Apache, PHP-FPM, WordPress dans /var/www/wordpress. Ajustez les chemins, mais ne faites pas « au doigt mouillé ». Confirmez d’abord.

Tâche 1 : Confirmer ce que voit le monde (statut HTTP, en-têtes, temps)

cr0x@server:~$ curl -sS -D- -o /dev/null https://example.com/
HTTP/2 502 
date: Fri, 27 Dec 2025 18:41:12 GMT
content-type: text/html
server: nginx

Sens : Nginx est joignable, mais l’amont (PHP-FPM) échoue ou met trop de temps.

Décision : Ne touchez plus aux fichiers WordPress. Allez consulter le journal d’erreurs Nginx et le statut/journaux PHP-FPM ensuite.

Tâche 2 : Identifier la pile web (Nginx vs Apache) et l’état des services

cr0x@server:~$ systemctl status nginx php8.2-fpm --no-pager
● nginx.service - A high performance web server and a reverse proxy server
     Loaded: loaded (/lib/systemd/system/nginx.service; enabled; preset: enabled)
     Active: active (running) since Fri 2025-12-27 18:02:19 UTC; 38min ago

● php8.2-fpm.service - The PHP 8.2 FastCGI Process Manager
     Loaded: loaded (/lib/systemd/system/php8.2-fpm.service; enabled; preset: enabled)
     Active: failed (Result: exit-code) since Fri 2025-12-27 18:39:58 UTC; 1min 14s ago

Sens : PHP-FPM est arrêté ; WordPress n’a même pas la chance de s’exécuter.

Décision : Inspectez les journaux journalctl de PHP-FPM ; probablement un changement de config, une extension manquante ou une contrainte de ressources.

Tâche 3 : Lire la raison de l’échec PHP-FPM (journal)

cr0x@server:~$ sudo journalctl -u php8.2-fpm -n 80 --no-pager
Dec 27 18:39:58 server php-fpm8.2[21983]: ERROR: failed to open configuration file '/etc/php/8.2/fpm/php-fpm.conf': Permission denied (13)
Dec 27 18:39:58 server systemd[1]: php8.2-fpm.service: Main process exited, code=exited, status=78/CONFIG
Dec 27 18:39:58 server systemd[1]: php8.2-fpm.service: Failed with result 'exit-code'.

Sens : Ce n’est pas WordPress. C’est un problème de permissions au niveau OS sur un fichier de configuration. Généralement causé par une règle de durcissement mal appliquée, une mauvaise propriété ou un mode de fichier cassé pendant une mise à jour de paquet.

Décision : Corriger les permissions de ce fichier (ou restaurer depuis le paquet), puis redémarrer PHP-FPM. Ne touchez pas encore aux plugins.

Tâche 4 : Valider les permissions du fichier de config et restaurer des modes sains

cr0x@server:~$ sudo ls -l /etc/php/8.2/fpm/php-fpm.conf
---------- 1 root root 4217 Dec 27 18:38 /etc/php/8.2/fpm/php-fpm.conf

Sens : Le mode est 000 ; personne ne peut le lire, y compris PHP-FPM au démarrage (selon la politique de la distribution). C’est cassé.

Décision : Restaurer typiquement en 644, redémarrer, retester HTTP. Si cela ramène le site, vous devez encore enquêter pourquoi il a changé pendant la mise à jour.

cr0x@server:~$ sudo chmod 644 /etc/php/8.2/fpm/php-fpm.conf
cr0x@server:~$ sudo systemctl restart php8.2-fpm
cr0x@server:~$ systemctl status php8.2-fpm --no-pager
● php8.2-fpm.service - The PHP 8.2 FastCGI Process Manager
     Loaded: loaded (/lib/systemd/system/php8.2-fpm.service; enabled; preset: enabled)
     Active: active (running) since Fri 2025-12-27 18:42:10 UTC; 3s ago

Sens : PHP-FPM est de nouveau sain.

Décision : Relancer curl. Si c’est toujours en erreur, pivotez maintenant vers les journaux au niveau application.

Tâche 5 : Vérifier le journal d’erreurs Nginx pour des indices en amont

cr0x@server:~$ sudo tail -n 40 /var/log/nginx/error.log
2025/12/27 18:41:11 [error] 1132#1132: *889 upstream sent too big header while reading response header from upstream, client: 203.0.113.21, server: example.com, request: "GET / HTTP/2.0", upstream: "fastcgi://unix:/run/php/php8.2-fpm.sock:", host: "example.com"

Sens : C’est un vrai mode d’échec après mise à jour : un plugin/thème modifie les cookies ou en-têtes et la réponse en amont dépasse les limites de buffer Nginx.

Décision : Si c’est le blocage actuel, ajustez temporairement les fastcgi buffers de Nginx comme mitigation, mais cherchez aussi le plugin qui génère des cookies/en-têtes énormes.

Tâche 6 : Capturer l’erreur fatale PHP réelle (activer le logging sans afficher aux utilisateurs)

N’activez pas display_errors en production. Consignez-la.

cr0x@server:~$ sudo grep -n "WP_DEBUG\|WP_DEBUG_LOG\|WP_DEBUG_DISPLAY" /var/www/wordpress/wp-config.php
88:define('WP_DEBUG', false);

Sens : Le debug logging est désactivé ; vous êtes peut-être aveugle.

Décision : Activez temporairement WP_DEBUG_LOG en gardant l’affichage désactivé. Reproduisez une fois, lisez le journal, puis revenez en arrière.

cr0x@server:~$ sudo sed -i "s/define('WP_DEBUG', false);/define('WP_DEBUG', true);\ndefine('WP_DEBUG_LOG', true);\ndefine('WP_DEBUG_DISPLAY', false);/g" /var/www/wordpress/wp-config.php
cr0x@server:~$ sudo -u www-data php -v
PHP 8.2.14 (cli) (built: Dec  5 2025 09:01:22) (NTS)

Sens : Vous avez activé le debug logging. Le CLI PHP est présent ; utile pour WP-CLI ou tests rapides.

Décision : Accédez une fois au point de défaillance, puis inspectez wp-content/debug.log.

Tâche 7 : Lire le journal de débogage WordPress et localiser le coupable

cr0x@server:~$ sudo tail -n 30 /var/www/wordpress/wp-content/debug.log
[27-Dec-2025 18:43:02 UTC] PHP Fatal error:  Uncaught Error: Call to undefined function mb_strlen() in /var/www/wordpress/wp-content/plugins/newsletter-pro/includes/parser.php:117
Stack trace:
#0 /var/www/wordpress/wp-settings.php(453): include_once()
#1 /var/www/wordpress/wp-config.php(90): require_once('...')
#2 /var/www/wordpress/wp-load.php(50): require_once('...')
#3 /var/www/wordpress/wp-blog-header.php(13): require_once('...')
#4 /var/www/wordpress/index.php(17): require('...')
#5 {main}
  thrown in /var/www/wordpress/wp-content/plugins/newsletter-pro/includes/parser.php on line 117

Sens : Le code du plugin a appelé mb_strlen(), mais l’extension PHP mbstring n’est pas chargée. Cela arrive souvent après une mise à jour PHP ou un changement de paquet.

Décision : Rétablir le service rapidement en désactivant le plugin ou en installant l’extension manquante. Choisissez le changement le moins risqué pour votre environnement.

Tâche 8 : Confirmer l’extension PHP manquante

cr0x@server:~$ php -m | grep -i mbstring || echo "mbstring not loaded"
mbstring not loaded

Sens : L’extension est absente.

Décision : Installer le paquet php-mbstring pour votre distribution/version PHP ; puis redémarrer PHP-FPM. Si vous ne pouvez pas installer rapidement (contrôle des changements), désactivez d’abord le plugin.

Tâche 9 : Désactiver un plugin sans wp-admin (renommer le répertoire)

cr0x@server:~$ cd /var/www/wordpress/wp-content/plugins
cr0x@server:~$ sudo mv newsletter-pro newsletter-pro.disabled
cr0x@server:~$ ls -1 | head
akismet
hello.php
newsletter-pro.disabled
woocommerce

Sens : WordPress ne peut plus charger un répertoire de plugin renommé ; il le désactivera effectivement au prochain chargement.

Décision : Retester le site. S’il revient, vous avez confirmé le coupable et gagné du temps pour installer mbstring et réactiver en sécurité.

Tâche 10 : Corriger rapidement le « verrouillage en mode maintenance »

cr0x@server:~$ sudo ls -la /var/www/wordpress/.maintenance
-rw-r--r-- 1 www-data www-data 52 Dec 27 18:37 /var/www/wordpress/.maintenance

Sens : WordPress a laissé un fichier de verrouillage de maintenance, généralement suite à une mise à jour interrompue.

Décision : Supprimez-le, puis testez de nouveau. S’il revient, les mises à jour échouent toujours (permissions, disque ou système de fichiers).

cr0x@server:~$ sudo rm -f /var/www/wordpress/.maintenance
cr0x@server:~$ curl -sS -o /dev/null -w "%{http_code}\n" https://example.com/
200

Tâche 11 : Vérifier l’espace disque et la pression d’inodes (les mises à jour écrivent)

cr0x@server:~$ df -h /var/www /tmp
Filesystem      Size  Used Avail Use% Mounted on
/dev/vda1        40G   39G  260M 100% /
tmpfs           1.9G   12M  1.9G   1% /tmp

Sens : Le système de fichiers racine est plein. Les mises à jour échoueront de manière créative, y compris écritures partielles et impossibilité de créer des fichiers temporaires.

Décision : Libérez de l’espace immédiatement (journaux, anciennes releases, caches). Puis relancez la mise à jour plus tard dans une fenêtre contrôlée. Vérifiez aussi les inodes si vous avez beaucoup de petits fichiers.

cr0x@server:~$ df -i /
Filesystem      Inodes  IUsed   IFree IUse% Mounted on
/dev/vda1      262144 261900     244  100% /

Sens : Épuisement des inodes. Échec classique WordPress avec trop de fichiers de cache ou de sauvegardes stockées localement.

Décision : Supprimez les répertoires à fort taux de changement (cache, tmp), déplacez les sauvegardes hors de l’hôte et définissez des politiques de rétention.

Tâche 12 : Vérifier propriété et permissions dans wp-content

cr0x@server:~$ sudo find /var/www/wordpress/wp-content -maxdepth 1 -type d -printf "%M %u:%g %p\n"
drwxr-xr-x root root /var/www/wordpress/wp-content
drwxr-xr-x root root /var/www/wordpress/wp-content/plugins
drwxr-xr-x root root /var/www/wordpress/wp-content/themes
drwxrwx--- www-data www-data /var/www/wordpress/wp-content/uploads

Sens : Si les plugins/themes sont possédés par root et non modifiables par l’utilisateur web, les mises à jour via le dashboard peuvent échouer en plein milieu. Ce n’est pas nécessairement une erreur (certaines équipes veulent du code immuable), mais dans ce cas vous devez déployer les mises à jour autrement.

Décision : Choisissez un modèle : soit code immuable (pipeline de déploiement ; désactiver les modifications via le dashboard), soit permettre à WordPress d’écrire (moins sûr). N’ayez pas le modèle intermédiaire maudit où les mises à jour fonctionnent à moitié.

Tâche 13 : Utiliser WP-CLI pour lister et désactiver les plugins (propre et auditable)

cr0x@server:~$ cd /var/www/wordpress
cr0x@server:~$ sudo -u www-data wp plugin list --status=active
+-------------------+----------+--------+---------+
| name              | status   | update | version |
+-------------------+----------+--------+---------+
| woocommerce       | active   | none   | 9.2.1   |
| wordpress-seo     | active   | none   | 23.1    |
| newsletter-pro    | active   | none   | 4.0.0   |
+-------------------+----------+--------+---------+

Sens : Vous pouvez gérer les plugins sans wp-admin. C’est la méthode adulte pour faire des changements d’urgence.

Décision : Désactivez d’abord les plugin(s) suspect(s) ; testez ; puis itérez.

cr0x@server:~$ sudo -u www-data wp plugin deactivate newsletter-pro
Plugin 'newsletter-pro' deactivated.

Tâche 14 : Basculer vers un thème par défaut sans wp-admin

cr0x@server:~$ sudo -u www-data wp theme list
+----------------+----------+--------+---------+
| name           | status   | update | version |
+----------------+----------+--------+---------+
| twentytwentyfour | inactive | none | 1.2     |
| custom-theme   | active   | none   | 3.8.7   |
+----------------+----------+--------+---------+

Sens : Si la mise à jour du thème a cassé le rendu, basculer de thème peut restaurer rapidement le front (l’admin reste généralement accessible).

Décision : Activez temporairement un thème par défaut, puis corrigez le code du thème hors production.

cr0x@server:~$ sudo -u www-data wp theme activate twentytwentyfour
Success: Switched to 'Twenty Twenty-Four' theme.

Tâche 15 : Diagnostiquer connectivité BDD vs config applicative

cr0x@server:~$ sudo -u www-data php -r "require '/var/www/wordpress/wp-config.php'; echo DB_HOST, PHP_EOL;"
localhost

Sens : Confirme ce que WordPress pense être l’hôte BDD (utile quand des variables d’environnement ou des includes sont impliqués).

Décision : Si des erreurs BDD apparaissent, testez la connectivité TCP/socket et les identifiants directement.

cr0x@server:~$ mysql -h localhost -u wpuser -p -e "SELECT 1;"
Enter password: 
1
1

Sens : La BDD est joignable et les identifiants fonctionnent depuis cet hôte.

Décision : Si WordPress dit toujours qu’il ne peut pas se connecter, suspectez un socket incorrect, un DB_HOST erroné (par ex. il faut 127.0.0.1), ou PHP sans extension mysqli.

Tâche 16 : Vérifier les extensions PHP pour MySQL

cr0x@server:~$ php -m | egrep -i "mysqli|pdo_mysql" || echo "no mysql extensions loaded"
mysqli
pdo_mysql

Sens : PHP peut parler à MySQL.

Décision : Si la BDD échoue toujours, vérifiez le nombre max de connexions et la santé de la BDD.

Tâche 17 : Vérifier la charge BDD et la saturation des connexions

cr0x@server:~$ mysql -uroot -p -e "SHOW STATUS LIKE 'Threads_connected'; SHOW VARIABLES LIKE 'max_connections';"
Enter password: 
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| Threads_connected | 198   |
+-------------------+-------+
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| max_connections | 200   |
+-----------------+-------+

Sens : Vous êtes à la limite. Une mise à jour qui augmente les requêtes (ou casse le cache) peut vous pousser dans « trop de connexions », que WordPress signale comme une erreur de connexion BDD.

Décision : Court terme : redémarrez PHP-FPM pour libérer les connexions inactives, scalez la BDD ou réduisez la concurrence. Moyen terme : corriger l’explosion de requêtes (souvent un plugin) et activer un cache objet approprié.

Tâche 18 : Confirmer ce qui a changé récemment (scan mtime)

cr0x@server:~$ sudo find /var/www/wordpress/wp-content -type f -mtime -1 -printf "%TY-%Tm-%Td %TH:%TM %p\n" | tail -n 10
2025-12-27 18:36 /var/www/wordpress/wp-content/plugins/newsletter-pro/includes/parser.php
2025-12-27 18:36 /var/www/wordpress/wp-content/plugins/newsletter-pro/newsletter-pro.php
2025-12-27 18:35 /var/www/wordpress/wp-content/themes/custom-theme/functions.php

Sens : Cela réduit la liste des suspects à ce qui a réellement changé.

Décision : Priorisez la désactivation/rollback des composants les plus récemment modifiés.

Blague #2 : Rien ne motive l’hygiène des logs comme une erreur 500 et un tableau de bord qui ne charge pas.

Trois mini-récits d’entreprise venus du terrain

Mini-récit 1 : L’incident causé par une mauvaise hypothèse

Ils exploitaient un site marketing WordPress sur une petite VM propre. L’équipe « savait » que c’était simple : Nginx + PHP-FPM + MariaDB. La mise à jour en question était « juste un patch de sécurité » pour un plugin de formulaire populaire.

Le patch est arrivé, et en quelques minutes le site a servi des 502 intermittents. Quelqu’un a supposé que c’était un bug de plugin et a commencé à rollbacker des versions de plugin. Une autre personne a augmenté les workers PHP-FPM. Le trafic continuait d’échouer par vagues.

La mauvaise hypothèse : « Si c’est un 502, c’est PHP. » Ce n’était pas le cas. La mise à jour du plugin a augmenté le nombre de requêtes HTTP sortantes (vérifications anti-spam, validation API) et la VM avait une politique de pare-feu sortant qui laissait tomber silencieusement ces connexions au lieu de les rejeter rapidement. Les workers PHP s’empilaient en attente de timeouts réseau. Nginx a timeouté en amont. 502.

La correction a été ennuyeuse : autoriser la sortie vers un petit ensemble d’endpoints API, définir des timeouts cURL raisonnables et limiter la durée des requêtes PHP-FPM. Le plugin n’était pas « cassé ». Le système était configuré pour échouer lentement, ce qui est le pire type d’échec en production.

L’item important du postmortem : quand vous voyez des 502, vérifiez si PHP meurt vite (fatales) ou meurt lentement (timeouts). Votre prochaine étape change complètement.

Mini-récit 2 : L’optimisation qui s’est retournée contre eux

Une autre organisation avait une pile WordPress + WooCommerce très fréquentée. Quelqu’un a décidé « d’optimiser » en activant un caching full-page agressif et en mettant en cache les utilisateurs connectés « parce que ça semblait OK en staging ». Ils ont aussi activé Redis object cache avec les réglages par défaut. C’était un vendredi. Bien sûr.

Puis ils ont mis à jour WooCommerce. La mise à jour a ajouté quelques cookies et ajusté la logique de session. Soudain des clients voyaient le panier des autres. Pas tout le temps. Juste assez pour être terrifiant. Le support a explosé.

Le retour de bâton était subtil : leur couche de cache ne variait pas correctement sur les cookies et l’état d’authentification après la mise à jour. L’ancienne logique fonctionnait par hasard avec le comportement des cookies précédent ; la nouvelle release a exposé l’hypothèse incorrecte. Techniquement le cache faisait ce qu’on lui disait. Opérationnellement, il a commis un petit crime.

La récupération a été un contournement rapide du cache pour les chemins liés à l’authentification et au panier, puis une réintroduction soignée du cache avec des règles de vary correctes. La leçon : le caching n’est pas un interrupteur, c’est un produit. Et « ça semblait bien » n’est pas un plan de test.

Mini-récit 3 : La pratique ennuyeuse mais correcte qui a sauvé la mise

Une troisième entreprise exécutait WordPress sur une paire de serveurs applicatifs derrière un load balancer, avec la base de données sur un stockage managé. Ils faisaient des mises à jour de plugins hebdomadaires. Rien de fancy. Mais ils avaient deux habitudes : (1) releases applicatives immuables (répertoires linkés) et (2) sauvegarde BDD nocturne avec tests de restauration vérifiés.

Une mise à jour a introduit une erreur fatale dans un plugin premium. Elle a mis le front hors service immédiatement. L’ingénieur on-call n’a pas débogué en direct. Il a fait la chose ennuyeuse : a pointé le symlink vers la release précédente, vidé l’opcache, et confirmé des 200. Durée totale de l’interruption : minutes.

Puis ils ont enquêté. La mise à jour du plugin nécessitait une extension PHP plus récente. En environnement dev, elle était installée par défaut. En prod, non. La fatale était légitime, mais elle n’était plus urgente car le service avait été rétabli.

Ils ont rollbacké plus tard le même jour après avoir installé l’extension et piné la version du plugin jusqu’à ce que le fournisseur clarifie les prérequis. La pratique ennuyeuse — releases que vous pouvez inverser en une commande — n’était pas glamour. Elle avait valeur monétaire.

Erreurs courantes : symptômes → cause racine → correction

1) « Briefly unavailable for scheduled maintenance. » pour toujours

Symptôme : Front et admin affichent le message de maintenance des heures après la mise à jour.

Cause racine : fichier .maintenance laissé après une mise à jour interrompue (timeout, permissions, disque plein).

Correction : Supprimez /var/www/wordpress/.maintenance. Puis vérifiez immédiatement l’espace disque et les permissions, sinon ça recommencera.

2) 502 Bad Gateway après mise à jour

Symptôme : Nginx renvoie 502 ; intermittent ou constant.

Cause racine : PHP-FPM arrêté, workers PHP bloqués, mismatch de socket ou problèmes de buffer amont.

Correction : Vérifiez systemctl status php*-fpm, lisez le journal, puis le journal d’erreurs Nginx pour « connect() failed », « upstream timed out » ou « too big header ». Corrigez le message réel, pas l’ambiance.

3) Écran blanc de la mort (WSOD)

Symptôme : Page blanche, peut-être 200 OK, sans contenu.

Cause racine : fatal PHP avec affichage des erreurs désactivé ; souvent un plugin/thème fatal.

Correction : Activez temporairement WP_DEBUG_LOG et inspectez wp-content/debug.log. Désactivez le plugin ou thème en échec. Revenez à l’état précédent après.

4) « Error establishing a database connection »

Symptôme : WordPress affiche immédiatement une erreur de connexion BDD.

Cause racine : BDD down, mauvais identifiants, connexions épuisées, problèmes DNS, ou extension PHP MySQL manquante après une mise à jour PHP.

Correction : Testez la connexion BDD depuis l’hôte, vérifiez DB_HOST, comparez Threads_connected et max_connections, assurez-vous que mysqli/pdo_mysql est chargé.

5) L’administration fonctionne, le front plante (ou inversement)

Symptôme : /wp-admin/ charge mais la page d’accueil répond 500, ou la page d’accueil marche mais l’admin est cassé.

Cause racine : échec limité au thème, problèmes de cache, ou plugin branché seulement sur les routes frontend.

Correction : Passez à un thème par défaut via WP-CLI et désactivez temporairement les plugins de cache/cache objet. Confirmez avec les journaux.

6) Redirections aléatoires / boucles de connexion après mise à jour

Symptôme : Impossible de rester connecté, redirections http/https, ou boucles autour de wp-login.php.

Cause racine : options siteurl/home mal réglées, en-têtes SSL du reverse proxy modifiés, ou cache qui ne varie pas correctement sur les cookies.

Correction : Confirmez les en-têtes proxy, assurez-vous que WordPress voit HTTPS correctement, vérifiez les valeurs site URL en BDD, purge des caches et correction des règles de vary.

7) L’UI de mise à jour indique succès, mais le code est à moitié mis à jour

Symptôme : Les numéros de version changent dans le tableau de bord, mais les fichiers sont manquants ou anciens.

Cause racine : permissions mixtes (certains répertoires écrasables, d’autres non), ou disque plein en plein extraction.

Correction : Arrêtez les mises à jour depuis le dashboard à moins que le serveur soit configuré pour cela. Utilisez une méthode de déploiement atomique, ou corrigez la propriété des fichiers de façon cohérente et surveillez disque/inodes.

Listes de contrôle / plan étape par étape

Le plan de récupération en 30 minutes (faites ceci, dans cet ordre)

  1. Commencez une timeline : notez l’heure, ce qui a été mis à jour et le symptôme actuel.
  2. Confirmez les codes : curl sur la page d’accueil et /wp-admin/.
  3. Vérifiez la santé des services : statut Nginx/Apache et PHP-FPM.
  4. Lisez les journaux : journal d’erreurs web, journal PHP-FPM, journal debug WordPress (activez le logging si besoin).
  5. Recherchez les bloqueurs évidents : .maintenance, disque plein, inode plein, permissions.
  6. Rollback de la plus petite unité : désactivez le plugin le plus récent ou changez de thème.
  7. Vérifiez la récupération : 200 OK, connexion admin fonctionnelle, parcours critique de paiement OK.
  8. Stabilisez le cache : purgez le cache de pages, réinitialisez le cache objet s’il est en cause.
  9. Capturez les preuves : sauvegardez la stack trace fatale et les diffs de configuration pertinents.
  10. Revenez sur les changements temporaires : désactivez WP_DEBUG et supprimez les logs sensibles si nécessaire.

Quand restaurer depuis une sauvegarde (et quand ne pas le faire)

  • Restaurer depuis une sauvegarde si : des migrations de schéma BDD ont été exécutées et vous ne pouvez pas les annuler ; des fichiers manquent dans le core ; vous avez des preuves de corruption ; vous n’avez pas de mécanisme de rollback propre.
  • Ne pas restaurer depuis une sauvegarde si : c’est juste un plugin fatal et vous pouvez le désactiver ; il manque une extension PHP ; un service est arrêté ; le disque est plein. Les sauvegardes servent aux pertes de données, pas aux diagnostics de base.

Garde-fous pour corrections en production

  • Privilégiez la désactivation d’un plugin plutôt que « l’éditer en direct ».
  • Faites un changement à la fois. Si vous ne pouvez pas expliquer ce que vous avez changé, vous ne pourrez pas le rollbacker.
  • Si vous devez modifier la configuration, capturez d’abord un diff.
  • Toute opération impliquant des écritures BDD doit être traitée comme risquée pendant la réponse à l’incident. Faites d’abord des investigations en lecture seule.

Faits intéressants et contexte historique (parce que ça aide)

  • WordPress a démarré en 2003 comme fork de b2/cafelog, et son écosystème de plugins a grandi plus vite que l’hygiène des dépendances de beaucoup.
  • Les mises à jour automatiques en arrière-plan pour les versions mineures du core sont devenues la norme des années plus tard, ce qui a réduit les fenêtres de vulnérabilité connues mais augmenté les incidents de « changement surprise » dans des environnements mal observés.
  • L’« écran blanc de la mort » n’est pas propre à WordPress ; c’est le résultat de fatales PHP confrontées à des configurations de production qui suppriment la sortie.
  • Les sauts de version PHP comptent : des changements comme un typage plus strict et des fonctionnalités dépréciées ont à plusieurs reprises cassé des thèmes et plugins anciens, surtout les solutions sur mesure.
  • Le cache objet dans WordPress est optionnel par conception ; quand il est activé il peut réduire drastiquement la charge BDD — ou amplifier les problèmes si la sérialisation, les TTL ou les clés de cache sont mal gérés.
  • Les écritures sur le système de fichiers font partie du mécanisme de mise à jour : WordPress télécharge généralement des archives zip, les extrait et échange des fichiers. C’est pourquoi les pannes disque/inode apparaissent comme des « problèmes de mise à jour ».
  • Les mises à jour de plugins peuvent inclure des migrations de base, et ces migrations s’exécutent souvent sous des timeouts de requête web — une contrainte architecturale qui peut créer des états à moitié appliqués.
  • Le fichier de verrouillage .maintenance est un mécanisme simple : WordPress le pose pendant les upgrades et le supprime ensuite. Si vous crashiez en plein upgrade, il reste. Simple, efficace, parfois agaçant.

FAQ

1) Je n’ai pas accès à wp-admin. Quelle est la façon la plus rapide de désactiver des plugins ?

Renommez le répertoire du plugin sous wp-content/plugins ou utilisez WP-CLI : wp plugin deactivate plugin-name. Le renommage fonctionne même lorsque PHP est à moitié cassé.

2) Est-il sûr d’activer WP_DEBUG en production pendant un incident ?

Oui, si vous gardez WP_DEBUG_DISPLAY à false et utilisez WP_DEBUG_LOG à true temporairement. Désactivez-le après avoir capturé l’erreur.

3) Pourquoi je vois 200 OK mais une page blanche ?

PHP peut planter avant de générer la sortie, et votre serveur peut renvoyer 200 avec un corps vide. C’est pourquoi les journaux comptent plus que le comportement du navigateur.

4) Dois-je rollbacker le core WordPress d’abord ou les plugins ?

Les plugins/thèmes d’abord. Les rollbacks du core sont plus risqués si une migration de base a eu lieu. La plupart des cassures après « une mise à jour » sont dues aux plugins/thèmes ou au changement d’environnement PHP.

5) Et si la mise à jour a changé le schéma de la base de données ?

Traitez cela avec précaution. Désactivez le plugin qui a déclenché la migration, évaluez quelles tables/options ont changé et préférez restaurer une sauvegarde BDD testée si vous ne pouvez pas l’inverser en confiance.

6) Je l’ai réparé en renommant un dossier de plugin. Comment le réactiver en toute sécurité ?

Ne vous contentez pas de le renommer et d’espérer. Corrigez d’abord la cause sous-jacente (extension PHP manquante, mismatch de version PHP). Puis réactivez de façon contrôlée : fenêtre de faible trafic, journaux ouverts et rollback rapide prêt.

7) Pourquoi une mise à jour de l’OS a cassé WordPress si je n’ai pas touché WordPress ?

Parce que WordPress s’exécute sur PHP, serveurs web et extensions. Si PHP a été mis à jour, des extensions peuvent manquer, des valeurs ini peuvent changer et le comportement d’OPcache peut évoluer.

8) Quelle est la surveillance minimale qui aurait simplifié ça ?

Checks d’état HTTP sur la page d’accueil et /wp-admin/, alertes sur le taux d’erreur, santé PHP-FPM (processus up, longueur de file), seuils disque/inodes et journaux d’erreurs centralisés.

9) Le caching peut-il causer « tout a planté » après une mise à jour ?

Absolument. Redirections en cache, en-têtes trop volumineux et règles de vary incorrectes peuvent faire qu’une application qui fonctionne semble cassée. Testez toujours en contournant le cache et purgez après une mise à jour majeure.

10) Quand dois-je suspecter le stockage ?

Si les mises à jour échouent à répétition, si vous voyez des changements de fichiers partiels, si vous obtenez des erreurs de permission ou si disque/inodes sont proches du plein. Les pannes de stockage se déguisent souvent en « bugs WordPress ».

Étapes suivantes après le retour en ligne

Une fois le site stabilisé, ne repartez pas immédiatement comme si de rien n’était. Profitez du calme pour éliminer les conditions qui ont rendu l’incident possible.

  1. Consignez le déclencheur racine : quelle mise à jour, quel composant, quel message de journal, quelle correction.
  2. Mettez les mises à jour sur des rails : adoptez des déploiements immuables (recommandé) ou rendez les permissions du système de fichiers cohérentes avec les mises à jour via le dashboard (moins recommandé).
  3. Ajoutez un mécanisme de rollback : releases versionnées, snapshots ou au moins une procédure de restauration testée.
  4. Auditez les extensions et versions PHP : définissez explicitement ce que la production doit avoir et faites-le respecter.
  5. Testez les mises à jour dans un environnement proche de la prod : même version PHP, même caching, mêmes en-têtes proxy, même jeu de plugins.
  6. Définissez des seuils pour disque et inodes : les échecs de mise à jour dus à un disque plein sont embarrassants parce qu’ils sont prévisibles.

L’objectif n’est pas « ne jamais casser ». L’objectif est de casser d’une manière qui soit rapide à diagnostiquer, rapide à rollbacker et difficile à répéter.

← Précédent
Remplacer vCenter par Proxmox : gains, pertes et contournements qui fonctionnent vraiment
Suivant →
DNS « Échec temporaire de la résolution de noms » : 5 causes principales et ordre de correction

Laisser un commentaire