«Після оновлення все зламалося»: 30-хвилинний план відновлення WordPress

Було корисно?

Ви оновили WordPress (або плагін, або PHP), оновили сторінку і ваш сайт став як місце злочину. Біла сторінка. 500-ті. «Briefly unavailable for scheduled maintenance.» Кошик не працює. Генеральний директор пише вам, ніби ви власноруч вимкнули інтернет.

Це виробничий план відновлення, написаний для людей, що підтримують реальні системи: вам потрібна швидка діагностика, безпечний відкат і мінімум героїчних зусиль. Вам не потрібні легенди. Потрібні секундомір, логи та план.

Правило 30 хвилин: діагностика важливіша за досконалість

Перші 30 хвилин ваша єдина задача — безпечно відновити сервіс, а не вирішувати WordPress як філософську проблему. Це означає робити швидкі, зворотні зміни, вести нотатки й не піддаватися спокусі «ще однієї дрібної правки».

Думайте як SRE: оберіть найменшу інтервенцію, яка поверне доступність, зберігаючи при цьому докази. Ваше майбутнє «я» скаже вам дякую під час пост-інцидентного розбору, коли не доведеться гадати, яка з восьми «дрібних правок» насправді все виправила.

Операційні пріоритети (впорядковано)

  1. Зупинити кровотечу: відновити робочу версію (навіть тимчасово деградовану, наприклад, відключивши плагін).
  2. Підтвердити, що зламалось: HTTP-помилки, PHP fatal, підключення до БД, помилки прав доступу, вичерпання ресурсів.
  3. Стабілізувати: усунути тригер, перевірити кеші, підтвердити фонові задачі.
  4. Лише потім шукати кореневу причину і планувати чисте виправлення.

Одна фраза, яку варто тримати на стікері: Парафраз: «Сподівання — не стратегія.» — часто приписують інженерам на кшталт Gene Kranz; ідея лишається корисною.

Жарт #1: Оновлення — як парашути: якщо ви тестуєте їх лише після стрибка, вам доведеться вчитися швидко.

План швидкої діагностики (перші/другі/треті перевірки)

Це найшвидша дорога до вузького місця. Не імпровізуйте. Дотримуйтеся послідовності, щоб не витратити 20 хвилин на шар, який не є винуватцем.

Перше: який користувач бачить результат?

  • 503 «режим обслуговування» або повідомлення «Briefly unavailable»: ймовірно файл .maintenance застряг або оновлення перервалось.
  • 500 / 502 / 504: проблема web-сервера ↔ PHP-FPM, PHP fatal, таймаут апстріму, вичерпання ресурсів.
  • «Error establishing a database connection»: креденшали БД, БД недоступна, неправильний сокет/хост, забагато підключень.
  • Біла сторінка: PHP fatal з вимкненим відображенням помилок або фатал на тему/плагіні на ранній стадії завантаження.
  • Сайт завантажується, але повільний: інвалідовані кеші, надмірні autoloaded опції, невідповідність обʼєктного кешу, повільні запити до БД.

Друге: перевірте логи, де ховається правда

  1. Лог помилок веб-сервера (Nginx/Apache).
  2. Лог PHP-FPM (або журнал systemd для php-fpm).
  3. Лог відладки WordPress (якщо увімкнено).
  4. Логи / статус бази даних (якщо симптоми — з БД).

Третє: зробіть найменший безпечний відкат

  • Вимкніть найновіший(і) плагін(и) або переключіться на іншу тему.
  • Відкачайте реліз коду (symlink або git deploy), якщо така можливість є.
  • Відновлюйте з бекапу тільки якщо відкат неможливий або схема БД змінилася і ви не можете її узгодити.

Скорочене рішення

Якщо ви не можете ідентифікувати проблемний шар за 5 хвилин, припиніть хаотичні дії і почніть збирати докази:

  • Поточні HTTP-статуси для / і /wp-admin/.
  • Останні 50 рядків логів помилок веб + PHP.
  • Нещодавні зміни файлів (mtime) у wp-content.

Що зазвичай означає «зламалося після оновлення»

1) Частково застосоване оновлення ядра WordPress

Оновлення ядра, яке перервалося (права, диск заповнений, таймаут), може залишити змішані версії. Симптоми: fatal в ядрових файлах, відсутні файли, випадкова поведінка та класичний блок «режим обслуговування».

2) Оновлення плагіна привело до fatal

Найпоширеніше. Плагін припускає певну версію PHP, наявність функції або іншого плагіна. Або має опечатку, що пройшла повз CI. Симптоми: біла сторінка, 500-ті, fatal з посиланням на шлях плагіна.

3) Оновлення теми або сумісність кастомної теми

Та ж історія, що й з плагінами, плюс спека у вигляді bespoke functions.php, написаного у 2017 і востаннє тестованого на PHP 7.4.

4) Під вас змінили версію PHP

Оновлення ОС, панелі або «дрібне» оновлення образу може підняти PHP. Симптоми: fatals типу «Call to undefined function», deprecated-попередження, які стають fatal (залежно від конфігурації), або відсутні розширення (mysqli, intl, imagick).

5) Мismatch кешу / обʼєктного кешу

Redis/Memcached плагіни обʼєктного кешу можуть ламатись, коли змінюється бекенд, плагін або формати серіалізації. Симптоми: адмін працює, але фронтенд падає, дивні цикли редиректів, переривчасті помилки, що зникають після очищення кешу.

6) Міграції БД і дрейф схем

Деякі плагіни запускають міграції при оновленні. Якщо вони провалюються наполовину, ви отримуєте зламані екрани адмінки, відсутні таблиці або довгі запити, що навантажують сайт.

7) «Все гаразд» — насправді сховище або права

Оновлення записують файли. Запис потребує місця, правильного owner/group і адекватних опцій монтування. Якщо диск повний або права неправильні, ви отримаєте часткові оновлення, повторні помилки і сайт, що виглядає як привид.

Практичні дії відновлення (команди, виводи, рішення)

Ці кроки призначені для виконання в порядку. Кожен містить: команду, реалістичний вивід, що це означає, і яке рішення прийняти.

Припущення: хост на Linux, Nginx або Apache, PHP-FPM, WordPress у /var/www/wordpress. Налаштуйте шляхи під себе, але не «на око». Спочатку перевірте.

Завдання 1: Підтвердити, що бачить світ (HTTP статус, заголовки, таймінг)

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

Значення: Nginx доступний, але апстрім (PHP-FPM) падає або таймаутиться.

Рішення: Не чіпайте файли WordPress. Перейдіть до логів Nginx і статусу/логів PHP-FPM.

Завдання 2: Визначити стек веба (Nginx vs Apache) та статус сервісів

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

Значення: PHP-FPM вниз; WordPress навіть не отримує шансу виконатися.

Рішення: Перевірте журнал PHP-FPM; ймовірно зміна конфігу, відсутнє розширення або брак ресурсів.

Завдання 3: Прочитати причину падіння 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'.

Значення: Це не WordPress. Це права на ОС для конфігураційного файлу. Зазвичай спричинено неправильно застосованим правилом жорсткої політики, помилковим власником або зіпсованими режимами файлу під час оновлення пакета.

Рішення: Відновити права на той файл (або відновити з пакета), потім перезапустити PHP-FPM. Поки що не чіпайте плагіни.

Завдання 4: Перевірити права конфігураційного файлу і відновити нормальні режими

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

Значення: Режим 000; ніхто не може його прочитати, включно з PHP-FPM при запуску (залежно від політик дистрибутиву). Це зламано.

Рішення: Відновити типовий 644, перезапустити, повторно протестувати HTTP. Якщо це повертає сайт, все одно треба зʼясувати, чому права змінились під час оновлення.

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

Значення: PHP-FPM знову здоровий.

Рішення: Повторно виконати curl. Якщо все ще не працює, тепер переходьте до логів на рівні застосунку.

Завдання 5: Перевірити лог помилок Nginx на предмет підказок щодо апстріму

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"

Значення: Це реальний режим відмови після оновлень: плагін/тема змінює cookie або заголовки, і відповідь апстріму перевищує буфери Nginx.

Рішення: Якщо це ваш поточний блокер, тимчасово відрегулюйте fastcgi буфери Nginx, але також знайдіть плагін, що генерує величезні cookie/заголовки.

Завдання 6: Захопити реальний PHP fatal (увімкнути логування без показу користувачам)

Не вмикайте display_errors у продакшені. Логуйте.

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

Значення: Логування відладки вимкнено; ви можете бути «сліпими».

Рішення: Тимчасово увімкніть WP_DEBUG_LOG, тримайте WP_DEBUG_DISPLAY вимкненим. Потім відтворіть помилку один раз, прочитайте лог, після чого поверніть налаштування.

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)

Значення: Ви ввімкнули логування відладки. PHP CLI доступний; зручно для WP-CLI або швидких тестів.

Рішення: Торкніться проблемного ендпоїнту один раз, потім перегляньте wp-content/debug.log.

Завдання 7: Прочитати лог відладки WordPress і знайти винуватця

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

Значення: Код плагіна викликав mb_strlen(), але розширення PHP mbstring не завантажено. Часто трапляється після оновлення PHP або змін пакунків.

Рішення: Швидко відновити сервіс, вимкнувши плагін або встановивши відсутнє розширення. Виберіть найменш ризиковий варіант для вашого середовища.

Завдання 8: Підтвердити відсутність PHP-розширення

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

Значення: Розширення відсутнє.

Рішення: Встановіть пакет php-mbstring для вашого дистрибутиву/версії PHP; потім перезапустіть PHP-FPM. Якщо швидко встановити неможливо (контроль змін), спочатку відключіть плагін.

Завдання 9: Вимкнути плагін без wp-admin (перейменувати каталог)

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

Значення: WordPress не зможе завантажити перейменований каталог плагіна; при наступному завантаженні він буде деактивований.

Рішення: Повторно протестуйте сайт. Якщо він повернувся, ви підтвердили винуватця і купили час, щоб встановити mbstring і безпечно знову увімкнути плагін.

Завдання 10: Швидко виправити «застряг у режимі обслуговування»

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

Значення: WordPress залишив файл блокування оновлення, зазвичай через перерване оновлення.

Рішення: Видаліть його, потім протестуйте знову. Якщо він повертається, оновлення все ще падають (права, диск або файлові системи).

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

Завдання 11: Перевірити місце на диску та іноди (оновлення потребують записів)

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

Значення: Кореневий розділ повний. Оновлення зазнаватимуть невдач у креативний спосіб, включно з частковим записом файлів і неможливістю створити тимчасові файли.

Рішення: Негайно звільніть місце (логи, старі релізи, кеші). Потім переінсталюйте оновлення у контрольованому вікні. Також перевірте іноди, якщо багато дрібних файлів.

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

Значення: Вичерпано іноди. Класична відмова WordPress при занадто великій кількості кешованих файлів або локальних бекапів.

Рішення: Видаліть директорії з інтенсивною змінністю (кеші, тимчасові), перенесіть бекапи за межі хоста і встановіть політику ретеншну.

Завдання 12: Перевірити власників файлів і права в 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

Значення: Якщо плагіни/теми належать root і не записувані веб-користувачем, оновлення через адмінку можуть падати на півшляху. Це не обовʼязково погано (деякі магазини хочуть незмінний код), але тоді оновлення повинні відбуватися іншим способом.

Рішення: Оберіть модель: або незмінні релізи (pipeline; заборонити редагування файлів), або дозволити WordPress писати (менш безпечно). Не залишайтеся посередині, де оновлення працюють частково.

Завдання 13: Використати WP-CLI для переліку й деактивації плагінів (чітко і аудитується)

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   |
+-------------------+----------+--------+---------+

Значення: Ви можете керувати плагінами без wp-admin. Це зрілий спосіб діяти в екстрених ситуаціях.

Рішення: Деактивуйте підозрілий(і) плагін(и) спочатку; протестуйте; потім ітеруйте.

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

Завдання 14: Переключитися на дефолтну тему без 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   |
+----------------+----------+--------+---------+

Значення: Якщо оновлення теми зламало рендеринг, переключення теми може швидко відновити фронтенд (адмін зазвичай лишається доступним).

Рішення: Тимчасово активуйте дефолтну тему, потім виправляйте код теми офлайн.

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

Завдання 15: Діагностувати підключення до БД vs конфіг застосунку

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

Значення: Підтверджує, який хост БД бачить WordPress (корисно, коли використовуються змінні оточення або include-файли).

Рішення: Якщо зʼявляються помилки БД, протестуйте TCP/сокет підключення і креденшали напряму.

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

Значення: БД доступна і креденшали працюють з цього хоста.

Рішення: Якщо WordPress все ще каже, що не може підключитись, підозрюйте неправильний сокет, некоректний DB_HOST (наприклад, потрібен 127.0.0.1) або відсутнє PHP-розширення mysqli.

Завдання 16: Перевірити PHP-розширення для MySQL

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

Значення: PHP може спілкуватися з MySQL.

Рішення: Якщо БД все ще падає, перевірте max_connections і стан БД.

Завдання 17: Перевірити навантаження БД і насичення підключень

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   |
+-----------------+-------+

Значення: Ви на межі. Оновлення, яке збільшує кількість запитів (або ламає кешування), може дотиснути вас до «забагато підключень», що WordPress інтерпретує як помилку підключення до БД.

Рішення: Короткостроково: перезапустити PHP-FPM, щоб звільнити підключення, масштабувати БД або знизити конкурентність. Середньостроково: виправити вибух запитів (часто причиною є плагін) і ввімкнути правильне обʼєктне кешування.

Завдання 18: Підтвердити, що змінилось нещодавно (скан 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

Значення: Це звужує список підозрюваних до того, що фактично змінилося.

Рішення: Пріоритезуйте відключення/відкат найсвіжіше змінених компонентів.

Жарт #2: Нічого так не мотивує порядок у логах, як 500 помилка і недоступна адмінка.

Три корпоративні історії з передової

Міні-історія 1: Інцидент через хибне припущення

Вони тримали маркетинговий сайт на акуратній VM. Команда «знала», що там просто: Nginx + PHP-FPM + MariaDB. Оновлення було «просто патчем безпеки» для популярного плагіна форм.

Патч впав, і за кілька хвилин сайт почав віддавати переривчасті 502. Хтось припустив, що це баг плагіна і почав відкат версій плагіна. Інша людина почала збільшувати кількість PHP-FPM воркерів. Трафік продовжував збоїти хвилями.

Хибне припущення: «якщо це 502, то це PHP». Ні. Оновлення плагіна збільшило кількість зовнішніх HTTP-запитів (перевірки спаму, валідація API), а VM мала вихідні firewall-правила, що мовчки відкидали ці зʼєднання замість швидкого відкидання. PHP-воркери накопичувалися, чекаючи таймаутів мережі. Nginx апстрім таймаутив. 502.

Виправлення було нудним: дозволити вихід на невелику множину API-ендпоїнтів, встановити розумні cURL-таймаути і обмежити час обробки запиту PHP-FPM. Плагін не був «зламаний». Система була налаштована так, щоб повільно падати — найгірший вид відмов у продакшені.

Пост-мортем: коли бачите 502, перевіряйте, чи PHP помирає швидко (fatals), або помирає повільно (таймаути). Наступні кроки суттєво відрізняються.

Міні-історія 2: Оптимізація, що зіграла злий жарт

Інша організація мала завантажений стік WordPress + WooCommerce. Хтось вирішив «оптимізувати», увімкнувши агресивне кешування сторінок і кешування залогінених користувачів «бо в стагінгу здавалося ок». Також ввімкнули Redis обʼєктний кеш із дефолтними налаштуваннями. Це було у п’ятницю. Звісно.

Потім оновили WooCommerce. Оновлення додало кілька cookie і змінило логіку сесій. Раптом клієнти почали бачити кошики один одного. Не завжди. Достатньо, щоб лячно. Підтримка взірвалася.

Провал був тонкий: їхній шар кешування неправильно варіював вміст по cookie і стану авторизації після оновлення. Стара логіка випадково працювала з попередньою поведінкою cookie; новий реліз вивів на поверхню цю хибну припущення. Технічно кеш робив те, що його просили. Операційно — скоїв маленький злочин.

Відновлення: швидко обійти кеш для залогінених і шляхів, повʼязаних з кошиком, потім обережно повернути кеш з правильними правилами vary. Глибша наука: кешування — не тумблер, це продукт. «Здається ок» — не план тестування.

Міні-історія 3: Нудна, але правильна практика, що врятувала день

Третя компанія тримала WordPress на парі ап-серверів за балансувальником, з базою на керованому сховищі. Вони робили щотижневі оновлення плагінів. Нічого надзвичайного. Але мали дві звички: (1) незмінні релізи (директорії зі symlink), і (2) нічний бекап БД з перевіреною відновлювальною процедурою.

Одне оновлення ввело fatal у преміум-плагіні. Воно миттєво впало фронтенд. Інженер на виклику не дебажив у живу. Він зробив нудну річ: вказав symlink на попередній реліз, очистив opcode cache і підтвердив 200. Загальний даунтайм: хвилини.

Пізніше розібралися. Оновлення плагіна вимагало нове PHP-розширення. У дев-середовищі воно було встановлене за замовчуванням. В проді — ні. Фатал був реальний, але більше не терміновий, бо сервіс відновлено.

Вони накотили вперед того ж дня після встановлення розширення і зафіксували версію плагіна, доки вендор не прояснив вимоги. Нудна практика — релізи, які можна відкотити однією командою — не була гламурною. Вона була дорожньою.

Поширені помилки: симптом → причина → виправлення

1) «Briefly unavailable for scheduled maintenance.» назавжди

Симптом: Фронтенд і адмінка показують повідомлення про обслуговування годинами після оновлення.

Коренева причина: Файл .maintenance залишився після перерваного оновлення (таймаут, права, диск повний).

Виправлення: Видаліть /var/www/wordpress/.maintenance. Потім негайно перевірте місце на диску і права файлів, інакше це повториться.

2) 502 Bad Gateway після оновлення

Симптом: Nginx повертає 502; періодично або постійно.

Коренева причина: PHP-FPM вимкнений, PHP-воркери зависли, невідповідний сокет або проблеми з буферами апстріму.

Виправлення: Перевірте systemctl status php*-fpm, читайте журнал, потім лог Nginx на предмет «connect() failed», «upstream timed out» або «too big header». Виправляйте саме повідомлення, а не просто настрій.

3) Біла сторінка (WSOD)

Симптом: Порожня сторінка, можливо 200 OK, без контенту.

Коренева причина: PHP fatal з вимкненим виводом помилок; часто фатал від плагіна/теми.

Виправлення: Тимчасово увімкніть WP_DEBUG_LOG і перевірте wp-content/debug.log. Вимкніть проблемний плагін або тему. Після цього поверніть налаштування відладки.

4) «Error establishing a database connection»

Симптом: WordPress негайно показує помилку підключення до БД.

Коренева причина: БД впала, неправильні креденшали, вичерпання підключень, проблеми DNS або відсутнє PHP MySQL-розширення після оновлення PHP.

Виправлення: Тестуйте логін у БД з хоста, перевірте DB_HOST, перевірте Threads_connected vs max_connections, переконайтеся, що завантажені mysqli/pdo_mysql.

5) Адмін працює, фронтенд ламається (або навпаки)

Симптом: /wp-admin/ завантажується, але головна сторінка дає 500, або навпаки.

Коренева причина: Збої лише у темі, проблеми з кешуванням або плагін, що підключається тільки для фронтенду.

Виправлення: Переключіться на дефолтну тему через WP-CLI і тимчасово відключіть плагіни кешування/обʼєктного кешу. Підтвердіть через логи.

6) Випадкові редиректи / цикли логіна після оновлення

Симптом: Неможливо залишитись залогіненим, редиректи між http/https або цикли навколо wp-login.php.

Коренева причина: Неправильно налаштовані опції siteurl/home, зміни в заголовках SSL від зворотного проксі або кешування, що неправильно варіює по cookie.

Виправлення: Підтвердіть проксі-заголовки, переконайтеся, що WordPress бачить HTTPS коректно, перевірте значення URL у БД, очистіть кеші і виправте правила vary.

7) UI оновлень показує успіх, але код частково оновлений

Симптом: Номери версій в дашборді змінились, але файли відсутні або старі.

Коренева причина: Змішані права (деякі директорії записувані, інші — ні) або диск повний під час розпакування.

Виправлення: Припиніть робити оновлення через адмінку, якщо сервер не сконфігурований для цього. Використовуйте атомарний метод деплою або виправте власників і стежте за диском/інодами.

Чеклісти / покроковий план

План відновлення за 30 хвилин (робіть у такому порядку)

  1. Почніть хронологію: запишіть час, що оновлювали і поточний симптом.
  2. Підтвердіть коди статусу: curl головну сторінку і /wp-admin/.
  3. Перевірте здоровʼя сервісів: статус Nginx/Apache і PHP-FPM.
  4. Читайте логи: лог веба, журнал PHP-FPM, лог відладки WordPress (увімкніть логування при потребі).
  5. Шукайте очевидні блокери: .maintenance, диск заповнений, іноди вичерпані, права.
  6. Відкотіть найменшу одиницю: вимкніть найновіший плагін або переключіться на іншу тему.
  7. Підтвердіть відновлення: 200 OK, можливість логіну, критичні шляхи (checkout) працюють.
  8. Стабілізуйте кешування: очистіть page cache, скиньте object cache, якщо він задіяний.
  9. Збережіть докази: збережіть стек фаталу і релевантні дифи конфігів.
  10. Поверніть тимчасові зміни відладки: вимкніть WP_DEBUG і за потреби видаліть чутливі логи.

Коли відновлювати з бекапу (і коли ні)

  • Відновлюйте з бекапу, якщо: міграції схеми БД виконалися й ви не можете їх скасувати; файли відсутні по всьому ядру; є докази корупції; у вас немає чистого механізму відкату.
  • Не відновлюйте з бекапу, якщо: це лише один фатальний плагін і ви можете його деактивувати; відсутнє PHP-розширення; сервіси впали; диск повний. Бекапи — для втрати даних, а не для базової діагностики.

Запобіжні правила для виправлень у продакшені

  • Надавайте перевагу деактивації плагіна над «редагуванням його на живо».
  • Робіть одну зміну за раз. Якщо не можете пояснити, що ви змінили, ви не зможете відкотити.
  • Якщо змінюєте конфіг, спершу зафіксуйте diff.
  • Всі дії, що пишуть у БД, вважаються ризиковими під час інциденту. Спочатку робіть дослідження лише для читання.

Цікавинки та історичний контекст (бо це допомагає)

  • WordPress почався у 2003 як форк b2/cafelog, і його екосистема плагінів зросла швидше, ніж у більшості людей встигла зрости культура залежностей.
  • Автоматичні фонові оновлення для мінорних релізів ядра стали стандартом пізніше, що зменшило вік експозиції відомих вразливостей, але збільшило «сюрпризні зміни» в погано моніторених середовищах.
  • «Біла сторінка смерті» не унікальна для WordPress; це результат фаталів PHP у продакшн-конфігах з приглушеним виводом.
  • Переходи версій PHP важливі: жорсткіше типізування та застарілі фічі неодноразово ламали старі теми й плагіни, особливо кастомні.
  • Обʼєктне кешування у WordPress опціональне за дизайном; коли ввімкнено, воно може суттєво зменшити навантаження на БД — або посилити дивну поведінку, якщо серіалізація, TTL або ключі кешу налаштовані неправильно.
  • Записи у файлову систему — частина механізму оновлення: WordPress зазвичай завантажує zip, розпаковує і міняє файли. Ось чому проблеми з диском/інодами проявляються як «проблеми оновлення».
  • Оновлення плагінів можуть містити міграції БД, і такі міграції часто запускаються в межах веб-запитів — архітектурне обмеження, що може створювати напівзастосовані стани.
  • Файл блокування .maintenance — простий механізм: WordPress створює його під час оновлення і видаляє після. Якщо ви вилетіли під час оновлення, файл лишається. Простий, ефективний, іноді дратує.

Поширені запитання

1) Я не можу зайти в wp-admin. Який найшвидший спосіб вимкнути плагіни?

Перейменуйте каталог плагіна в wp-content/plugins або використайте WP-CLI: wp plugin deactivate plugin-name. Перейменування працює навіть коли PHP частково зламаний.

2) Чи безпечно увімкнути WP_DEBUG у продакшені під час інциденту?

Так, якщо тримати WP_DEBUG_DISPLAY у false і тимчасово увімкнути WP_DEBUG_LOG. Після захоплення помилки вимкніть назад.

3) Чому бачу 200 OK, але порожню сторінку?

PHP може фаталити до виводу контенту, і сервер усе одно поверне 200 з порожнім тілом. Саме тому логи важливіші за поведінку браузера.

4) Що відкочувати спочатку: ядро WordPress чи плагіни?

Спочатку плагіни/теми. Відкат ядра ризикованіший, якщо вже виконано оновлення бази даних. Більшість зламів після «оновлення» — це плагіни/теми або зміни середовища PHP.

5) Що робити, якщо оновлення змінило схему бази даних?

Дійте обережно. Вимкніть плагін, що ініціював міграцію, проаналізуйте які таблиці/опції змінились і віддавайте перевагу відновленню з перевіреного бекапу, якщо не можете впевнено відкотити зміни.

6) Я виправив, перейменувавши папку плагіна. Як безпечно його знову ввімкнути?

Не просто перейменовуйте назад і сподівайтеся. Спершу виправте основну причину (відсутнє PHP-розширення, несумісність версії PHP). Потім увімкніть у контрольований проміжок: низький трафік, логи відкриті, готовий швидкий відкат.

7) Чому оновлення ОС зламало WordPress, якщо я не чіпав WordPress?

Бо WordPress працює на PHP, веб-серверах і розширеннях. Якщо PHP оновився, деякі розширення можуть бути відсутні, ini-конфіги можуть змінитись, і поведінка OPcache може відрізнятися.

8) Який мінімальний моніторинг полегшив би це?

HTTP-чекі для головної сторінки і /wp-admin/, алерти на зростання помилок, здоровʼя PHP-FPM (процес вгору, довжина черги), пороги диску/інодів і централізовані логи помилок.

9) Чи може кешування спричинити «все зламалося» після оновлення?

Абсолютно. Кешовані редиректи, надмірні заголовки і неправильні правила vary можуть зробити робочий додаток нефункціональним. Завжди тестуйте в обхід кешу і очищуйте його після великих оновлень.

10) Коли підозрювати проблеми зі сховищем?

Якщо оновлення падають повторно, якщо бачите часткові зміни файлів, якщо є помилки прав доступу або диск/іноди близькі до заповнення. Збої сховища часто маскуються під «баги WordPress».

Наступні кроки після відновлення сервісу

Коли сайт стабілізовано, не поспішайте повертатися до звичного ритму. Використайте спокій, щоб усунути умови, які дозволили інциденту статися.

  1. Запишіть кореневий тригер: яке оновлення, який компонент, яке лог-повідомлення, яке виправлення.
  2. Впровадьте процес оновлень: або незмінні деплої (рекомендовано), або зробіть права файлової системи узгодженими з оновленнями через адмінку (менш рекомендовано).
  3. Додайте механізм відкату: версійовані релізи, знімки або хоча б перевірену процедуру відновлення.
  4. Аудит розширень і версій PHP: чітко визначте, що має бути в продакшені, і забезпечте це.
  5. Тестуйте оновлення у prod-подібному середовищі: така сама версія PHP, те саме кешування, ті самі заголовки проксі, той самий набір плагінів.
  6. Встановіть пороги для диску й інодів: збій оновлень через повний диск — принизливо, бо це передбачувано.

Мета не в «ніколи не ламатися». Мета — ламатися так, щоб було швидко діагностовано, швидко відкотити і важко повторити.

← Попередня
Замінити vCenter на Proxmox: що ви отримуєте, що втрачаєте та робочі обходи, які справді працюють
Наступна →
DNS «Тимчасова помилка при розв’язуванні імен»: 5 кореневих причин та порядок виправлення

Залишити коментар