Ви натискаєте оновити сторінку. Банер усе ще відображається. Головна сторінка недоступна, начальник питає, чи «інтернет зламався», а WordPress мило стверджує, що він «короткочасно недоступний».
Це повідомлення має триматися секунди. Коли воно застрягає, майже ніколи це не таємниця. Це дуже проста блокувальна файлова позначка, невдале оновлення або проблема з правами/диском, що ховається під дешевою маскою. Розгляньмо це як інцидент: підтвердіть вплив, ідентифікуйте блокуючий механізм, відновіть сервіс і потім усуньте умови, які це спричинили.
Що насправді означає повідомлення про обслуговування
Режим обслуговування WordPress — це не «режим» у сучасному сенсі feature-flag. Це блокування на основі файлу.
Під час оновлення (ядро, плагін, тема, переклади) WordPress створює файл з назвою .maintenance у корені сайту (той самий каталог, що й wp-config.php).
Поки цей файл існує і виглядає «достатньо свіжим», WordPress перериває звичайний рендер сторінки і повертає повідомлення про обслуговування.
Дизайн навмисно простий. Оновлення коду на диску під час виконання PHP-запитів — це мінне поле. Файлове блокування — це спосіб WordPress сказати:
«Відійдіть. Я замінюю частини».
Режим обслуговування має очищуватися автоматично в кінці успішного оновлення. Коли цього не відбувається, файл блокування лишається, або WordPress продовжує думати, що оновлення триває, бо щось застрягло: напіврозпакований пакет, проблема з правами, заповнений диск, кешована відповідь або PHP-процес, що загинув посеред виконання.
Повідомлення чесно говорить одне: воно дійсно з’являється під час запланованого обслуговування. Брехня в слові «короткочасне».
Як WordPress вирішує показувати повідомлення
На високому рівні WordPress робить таке:
- Створює
.maintenanceз міткою часу. - Запускає процес оновлення (завантаження, розпакування, копіювання, можливо запуск оновлень БД).
- Видаляє
.maintenanceпо завершенні.
Якщо процес оновлення переривається—таймаут HTTP, фатальна помилка PHP, збій запису у файлову систему, убитий робочий процес, крах або хтось натиснув «Оновити все» і закрив вкладку посеред запиту—крок очистки може ніколи не відбутися.
Жарт №1: режим обслуговування WordPress — як табличка «Не турбувати» — чудово, поки покоївка не повертається і ви не живете з вчорашніми рушниками.
Цікаві факти та трохи історії (бо це важливо)
Якщо ви експлуатуєте WordPress у продакшені, корисно знати, які припущення закладені в механізмах оновлення й блокувань. Ось конкретні факти, що пояснюють, чому ця проблема продовжує виникати у 2025 році:
- Блокування — це файл, а не прапорець у базі даних. Такий вибір сягає ранньої епохи WordPress: запис у файлову систему тоді вважали дешевшим і безпечнішим для спільного хостингу, ніж зміни в схемі БД.
- Автоматичні фонова оновлення з’явилися у WordPress 3.7 (2013). Раніше оновлення були переважно ручними й інтерактивними, тому збої помічали швидше — роздратовані люди.
- Повідомлення про обслуговування навмисно узагальнене. Воно уникає розкриття внутрішніх деталей анонімним користувачам — це добре для безпеки, але погано для зручності оператора.
- Оновлення ядра використовують модель «копіюй, потім поміняй місцями». WordPress намагається зменшити стани часткового оновлення, але плагіни/теми все ще вразливі до напівзаписаних директорій, якщо процес переривається.
- Логіка файлових облікових даних існує через те, що на багатьох сайтах немає прав запису. Ця спадщина з FTP-орієнтованого спільного хостингу досі впливає на типи збоїв (запити облікових даних, неможливість запису, мовчазні часткові збої).
- Оновлення перекладів — це окремий потік оновлень. Вони теж можуть запускати режим обслуговування, навіть коли ви думаєте «ми нічого не змінювали».
- Об’єктні та повно-сторінкові кеші можуть переживати блокування. Ви можете видалити
.maintenance, але сервіс іще віддає банер, якщо кеш на рівні edge вирішив, що це «контент». - Blue/green розгортання зробило це рідкіснішим — до того, як люди знову почали оновлювати живі ноди. В контейнеризованих середовищах оновлення на диску всередині запущеного контейнера — це сучасний аналог редагування продакшна вручну.
- Деякі провайдери додають власні перемикачі «maintenance». Managed WordPress платформи можуть показувати те саме повідомлення через правила проксі, а не сам WordPress.
Швидкий план діагностики (перший/другий/третій)
Ви хочете найкоротший шлях до «сайт працює», не створюючи більш цікавого інциденту. Ось порядок дій, який працює, коли ви на виклику і ваша кава ще вариться.
Перший: підтвердіть, чи це WordPress, чи edge вас обманює
- Обійдіть кеші й перевірте origin напряму (або принаймні з заголовками, що скасовують кеш).
- Якщо банер зберігається тільки через CDN/WAF, але на origin його немає — це інцидент кешування, а не WordPress.
Другий: перевірте наявність .maintenance та його мітку часу
- Якщо
.maintenanceіснує і старий — видаліть його і перевірте ще раз. - Якщо він новий і оновлення справді тривають, не видаляйте файл наосліп — переконайтесь, що процес оновлення не копіює ще файли.
Третій: знайдіть оновлення, яке зірвалося, і чому
- Перегляньте логи PHP-FPM/Apache/Nginx на наявність фаталів/таймаутів під час оновлення.
- Перевірте місце на диску та виснаження інодів (так, іноди все ще портять дні).
- Перевірте права/володіння: чи може PHP-користувач записувати в
wp-contentі (для ядра) у корінь WordPress? - Перевірте артефакти в
wp-content/upgrade, що можуть застрягти.
Чому воно застрягає: реальні режими відмов
1) Файл .maintenance не було видалено
Найпоширеніший випадок. Запит вийшов по таймауту, робочий процес PHP впав, хтось покинув вкладку або вебсервер перезапустився посеред оновлення.
У WordPress немає надійного фонової «прибиральниці», яка чистить після катастрофічних переривань.
Якщо ви видалите файл і все завантажиться, ви не «виправили» оновлення — ви зняли блокування. Іноді цього достатньо. Іноді ви просто розблокували користувачів, лишивши напівоновлений плагін, який пізніше впаде.
2) Часткове оновлення: каталог плагіна/теми в некоректному стані
Оновлення можуть залишити:
- Папку плагіна без критичних файлів (автозавантажувачі, головний файл плагіна).
- Нову версію, розпаковану в тимчасову директорію, але не переміщену на місце.
- Мікс старих і нових файлів через збої прав під час копіювання.
Видалення .maintenance може просто виявити реальну проблему: фатальні помилки, білий екран або зациклення входу в адмінці.
3) Невідповідність прав/володіння файлової системи
Для оновлень WordPress потрібен доступ на запис. На багатьох серверах код належить користувачу деплою (або root), але PHP працює як www-data (або подібний).
Тоді оновлення зриваються наполовину: zip завантажено, розпакування не вдається, очистка не виконується, .maintenance лишається.
4) Проблеми зі сховищем: заповнений диск, іноди, повільний I/O або збої мережевого сховища
Як інженеру з зберігання: тут «короткочасно» перестає бути правдою.
Оновлення інтенсивно пишуть: завантаження, розпакування (безліч дрібних файлів), перейменування, видалення.
Якщо диск заповнений або таблиця інодів порожня, або бекенд NFS/EFS/SMB має проблеми, оновлення може зависнути або впасти на випадковому кроці.
5) Рівні кешування продовжують віддавати банер після виправлення
CDN, зворотні проксі та плагіни кешування WordPress можуть кешувати відповідь обслуговування, як ніби це звичайна сторінка.
Origin здоровий, але edge продовжує відтворювати погану новину.
6) Конкурентні оновлення або «Оновити все» атакують одночасно
Кілька адміністраторів, що одночасно натискають кнопки оновлення — недооцінений генератор хаосу.
Навіть із блокуванням ви можете отримати перекриваючі спроби, які залишають тимчасові директорії й невідповідні стани.
7) «Режим обслуговування» від хостера або оновлення платформи
Деякі платформи показують те саме повідомлення під час знімків, міграцій або патчів. У такому разі видалення .maintenance не допоможе, бо WordPress не є джерелом цього повідомлення.
Практичні завдання з командами: діагностувати, вирішити, виправити
Нижче реальні завдання, які можна виконати на типовому хості Linux. Кожне включає: команду, що означає вивід, і як вирішувати. Налаштуйте шляхи під ваш Докрут. Припустимо, корінь WordPress — /var/www/example.com/public.
Завдання 1: Підтвердіть, що ви бачите origin, а не кешований edge
cr0x@server:~$ curl -sS -D- -o /dev/null -H 'Cache-Control: no-cache' https://example.com/ | sed -n '1,20p'
HTTP/2 503
date: Sat, 27 Dec 2025 12:01:11 GMT
content-type: text/html; charset=UTF-8
cache-control: no-cache, must-revalidate, max-age=0
server: nginx
Що це означає: HTTP 503 узгоджується з режимом обслуговування WordPress. Якби ви бачили заголовки на кшталт x-cache: HIT або специфічні заголовки CDN, варто підозрювати кешування.
Рішення: Якщо відповідь 503 і на origin, переходьте до перевірок на сервері. Якщо origin повертає 200, а edge — 503, очистіть/анулюйте кеш і перегляньте правила CDN.
Завдання 2: Перевірте, чи існує .maintenance (і де)
cr0x@server:~$ sudo -u www-data bash -lc 'cd /var/www/example.com/public && ls -la .maintenance || echo "no .maintenance"'
-rw-r--r-- 1 www-data www-data 55 Dec 27 11:43 .maintenance
Що це означає: Файл існує і читабельний. Його наявність сама по собі може викликати банер.
Рішення: Перевірте свіжість мітки часу наступним кроком. Якщо файл старий, його зазвичай можна видалити. Якщо він нещодавній — переконайтесь, що процес оновлення справді не виконується.
Завдання 3: Перегляньте вміст .maintenance
cr0x@server:~$ sudo -u www-data bash -lc 'cd /var/www/example.com/public && cat .maintenance'
<?php $upgrading = 1766835803; ?>
Що це означає: У файлі зберігається UNIX-мітка часу. WordPress використовує її, щоб визначити, чи є блокування «застарілим».
Рішення: Перетворіть її на людський час і порівняйте з поточним часом.
Завдання 4: Перетворіть мітку оновлення і оцініть, чи застаріле
cr0x@server:~$ date -d @1766835803
Sat Dec 27 11:43:23 UTC 2025
Що це означає: Тепер ви знаєте, коли почалося обслуговування.
Рішення: Якщо це було понад 30 хвилин тому і оновлення не триває — вважайте, що блокування застрягло, і видаліть файл після перевірки логів на наявність збоїв.
Завдання 5: Перевірте, чи процес оновлення активно працює (PHP-FPM воркери, unzip, wp-cli)
cr0x@server:~$ ps aux | egrep 'wp-cli|wordpress|unzip|php.*(update|upgrade)' | grep -v egrep
www-data 21904 0.2 1.1 312000 46000 ? S 11:42 0:02 php-fpm: pool www
Що це означає: Нічого очевидного, окрім звичайних PHP-воркерів, не працює.
Рішення: Можна вважати, що оновлення не в процесі. Перейдіть до очистки: видаліть блокування і потім перевірте цілісність.
Завдання 6: Безпечно видаліть .maintenance і перевірте
cr0x@server:~$ sudo -u www-data bash -lc 'cd /var/www/example.com/public && rm -v .maintenance'
removed '.maintenance'
Що це означає: Блокування зникло.
Рішення: Негайно перевірте сайт і адмінку. Якщо все завантажується, вам усе ще потрібно підтвердити, що оновлення не залишили код напівзламаним.
Завдання 7: Перевірте робочий каталог оновлення, що сигналізує про перервані оновлення
cr0x@server:~$ sudo -u www-data bash -lc 'cd /var/www/example.com/public && ls -la wp-content | sed -n "1,60p"'
total 64
drwxr-xr-x 9 www-data www-data 4096 Dec 27 11:42 .
drwxr-xr-x 5 www-data www-data 4096 Dec 27 11:40 ..
drwxr-xr-x 2 www-data www-data 4096 Dec 27 11:42 upgrade
drwxr-xr-x 36 www-data www-data 4096 Dec 27 11:10 plugins
drwxr-xr-x 8 www-data www-data 4096 Dec 27 10:55 themes
Що це означає: Існує директорія upgrade. Це нормально під час оновлень; підозріло, якщо вона застрягає, повна сміття.
Рішення: Перевірте її вміст. Якщо там напіврозпаковані артефакти з кількагодинною давністю — очистіть після перевірки, що оновлення не триває.
Завдання 8: Перегляньте вміст wp-content/upgrade
cr0x@server:~$ sudo -u www-data bash -lc 'cd /var/www/example.com/public && find wp-content/upgrade -maxdepth 2 -type f | head'
wp-content/upgrade/temp-backup/plugin-akismet.1766835740.zip
wp-content/upgrade/akismet/akismet.php
Що це означає: У вас лишилися артефакти. Не завжди шкідливо, але ознака того, що шлях оновлення не завершився коректно.
Рішення: Якщо сайт стабільний, можна видалити застарілий тимчасовий вміст upgrade, щоб уникнути майбутніх колізій і звільнити місце.
Завдання 9: Перевірте вільне місце на диску (оновлення відмовляються при нестачі місця)
cr0x@server:~$ df -h /var/www/example.com/public
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 40G 39G 300M 99% /
Що це означає: Використання 99%. Оновлення потребують резерву для завантаження zip і розпакування. 300MB — це «одне оновлення плагіна від сорому».
Рішення: Звільніть простір перед повторною спробою оновлень. Інакше ви повторите інцидент.
Завдання 10: Перевірте використання інодів (мовчазний вбивця операцій з великою кількістю дрібних файлів)
cr0x@server:~$ df -i /var/www/example.com/public
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/sda1 2621440 2621200 240 100% /
Що це означає: Фактично нуль інодів. Розпакування оновлень WordPress створює тисячі файлів; виснаження інодів робить «запис» неможливим, навіть якщо місце є.
Рішення: Знайдіть і видаліть inode-важкий непотріб (каталоги кешу, старі резервні копії, тимчасові файли). Потім повторіть оновлення.
Завдання 11: Перевірте володіння файлами та права в корені WordPress
cr0x@server:~$ sudo bash -lc 'cd /var/www/example.com/public && stat -c "%U:%G %a %n" wp-config.php wp-content wp-admin | sed -n "1,10p"'
root:root 640 wp-config.php
root:root 755 wp-content
root:root 755 wp-admin
Що це означає: Все належить root. Якщо PHP працює як www-data, WordPress не зможе писати оновлення, якщо ви не налаштували методи файлової системи/ACL.
Рішення: Вирішіть вашу операційну модель: або (a) деплой через CI/CD і робити іммутабельні релізи, або (b) дозволити WordPress писати, виправивши володіння/ACL. Не робіть напівзаходів.
Завдання 12: Підтвердіть користувача виконання PHP і чи може він писати
cr0x@server:~$ ps -o user,group,comm -C php-fpm8.2 2>/dev/null | head
USER GROUP COMMAND
root root php-fpm8.2
www-data www-data php-fpm8.2
Що це означає: Воркер-рои запускаються як www-data.
Рішення: Переконайтесь, що www-data має права запису туди, де відбуваються оновлення (зазвичай wp-content і іноді повний корінь для оновлень ядра). Якщо ви не можете цього дозволити — припиніть робити in-place оновлення.
Завдання 13: Запустіть WP-CLI для перевірки цілісності ядра і наявних оновлень
cr0x@server:~$ sudo -u www-data bash -lc 'cd /var/www/example.com/public && wp core verify-checksums'
Success: WordPress installation verifies against checksums.
Що це означає: Файли ядра відповідають очікуваним контрольним сумам для вашої версії. Добрий знак, що ядро не напівоновлене.
Рішення: Якщо ця перевірка неуспішна — плануйте перевстановлення файлів ядра (не чіпаючи wp-content) або відновлення з відомого артефакту.
Завдання 14: Визначте, що саме оновлювалося, коли все зависло
cr0x@server:~$ sudo -u www-data bash -lc 'cd /var/www/example.com/public && wp plugin list --update=available'
+-------------------+----------+-----------+---------+
| name | status | update | version |
+-------------------+----------+-----------+---------+
| akismet | active | available | 5.3 |
| woocommerce | active | available | 8.4.0 |
+-------------------+----------+-----------+---------+
Що це означає: Є доступні оновлення; зависання найбільш ймовірно сталося під час одного з них (або під час оновлень ядра/тем).
Рішення: Не натискайте «update all» знову. Оновлюйте по одному компоненту після стабілізації місця/прав, спостерігаючи логи.
Завдання 15: Перевірте нещодавні помилки PHP, що часто супроводжують невдалі оновлення
cr0x@server:~$ sudo tail -n 60 /var/log/php8.2-fpm.log
[27-Dec-2025 11:42:19] WARNING: [pool www] child 22001 said into stderr: "PHP Fatal error: Uncaught Error: Class 'Automattic\WooCommerce\Internal\DependencyManagement\Container' not found in /var/www/example.com/public/wp-content/plugins/woocommerce/woocommerce.php:45"
[27-Dec-2025 11:42:19] WARNING: [pool www] child 22001 said into stderr: "PHP Stack trace: #0 {main} thrown in /var/www/example.com/public/wp-content/plugins/woocommerce/woocommerce.php on line 45"
Що це означає: Плагін у некоректному стані (відсутній клас). Класичний випадок часткового оновлення: одні файли переміщено, інші — ні.
Рішення: Відновіть каталог цього плагіна з відомої робочої версії (резервна копія/артефакт) або перевстановіть через WP-CLI. Не видаляйте випадкові файли без плану.
Завдання 16: Перевстановіть зламаний плагін коректно (без гадань)
cr0x@server:~$ sudo -u www-data bash -lc 'cd /var/www/example.com/public && wp plugin deactivate woocommerce && wp plugin install woocommerce --force --activate'
Plugin 'woocommerce' deactivated.
Installing WooCommerce (9.1.0)
Downloading installation package from https://downloads.wordpress.org/plugin/woocommerce.9.1.0.zip...
Unpacking the package...
Installing the plugin...
Plugin installed successfully.
Activating 'woocommerce'...
Plugin 'woocommerce' activated.
Success: Installed 1 of 1 plugins.
Що це означає: Ви замінили файли плагіна на узгоджений набір і повторно активували його.
Рішення: Протестуйте критичні сценарії (оформлення замовлення, вхід, адмінка). Якщо це комерційний плагін, не робіть висновків, що «активовано» = «працює коректно».
Завдання 17: Перевірте журнали вебсервера на помилки прав/перейменування під час оновлення
cr0x@server:~$ sudo tail -n 80 /var/log/nginx/error.log
2025/12/27 11:42:18 [error] 21011#21011: *4411 FastCGI sent in stderr: "PHP message: PHP Warning: rename(/var/www/example.com/public/wp-content/plugins/akismet,/var/www/example.com/public/wp-content/plugins/akismet.old): Permission denied" while reading response header from upstream, client: 203.0.113.50, server: example.com, request: "POST /wp-admin/update.php?action=upgrade-plugin HTTP/2.0"
Що це означає: WordPress намагався перейменувати директорії як частину оновлення і отримав Permission denied.
Рішення: Виправте володіння/ACL, потім повторіть оновлення. Інакше воно завжди збиратиметься з помилкою, зазвичай на кроці перейменування.
Завдання 18: Виправте володіння для моделі «WordPress оновлює себе» (думка, але поширено)
cr0x@server:~$ sudo chown -R www-data:www-data /var/www/example.com/public/wp-content
Що це означає: Тепер PHP може записувати до wp-content. (Можливо, також потрібен доступ до кореня для оновлень ядра, залежно від моделі).
Рішення: Якщо ви працюєте з іммутабельними деплоями — не робіть цього. Натомість вимкніть оновлення через адмінку і пуште зміни через конвеєр.
Завдання 19: Очистіть кеші, які можуть відтворювати сторінку обслуговування
cr0x@server:~$ sudo -u www-data bash -lc 'cd /var/www/example.com/public && wp cache flush'
Success: The cache was flushed.
Що це означає: Об’єктний кеш WordPress очищено (працює з деякими бекендами кешу; залежить від конфігурації).
Рішення: Якщо у вас є окремий повно-сторінковий кеш (Nginx FastCGI cache, Varnish, CDN) — очистіть його теж. Якщо очистити неможливо, принаймні обійдіть кеш і підтвердіть здоров’я origin.
Завдання 20: Перевірте HTTP-статус і тіло після виправлень
cr0x@server:~$ curl -sS -D- -o /dev/null https://example.com/ | sed -n '1,15p'
HTTP/2 200
date: Sat, 27 Dec 2025 12:09:07 GMT
content-type: text/html; charset=UTF-8
server: nginx
Що це означає: Ви повернулися до 200 OK.
Рішення: Інцидент не закінчений, доки ви не підтвердите, що ключові сторінки й дії в адмінці працюють, і поки не усунете базову причину (місце, права, процес оновлення).
Три міні-історії з корпоративної практики
Міні-історія 1: Інцидент через хибне припущення
Середня компанія використовувала WordPress за CDN і WAF, з окремим кластером origin. Маркетинг запланував «невелике оновлення плагіна» за п’ятнадцять хвилин до анонсу продукту.
Хтось побачив банер обслуговування і зробив те, що радить інтернет: видалив .maintenance на одному origin-ноді. Банер залишився.
Хибне припущення було тонким: вони вважали, що банер генерується origin під час їхнього оновлення. Ні. CDN кешував відповідь 503 довше, ніж очікували, через правило на edge, яке мало захищати origin під час відмов. Воно трактувало 503 як кешоване «щоб зменшити навантаження».
Тим часом оновлення пройшло на двох нодах і зазнало невдачі на одній. Флот опинився в стані split-brain: частина нод віддавала оновлений плагін, одна нода мала напівкаталог і видавала фатали, а edge із задоволенням відтворював сторінку обслуговування з кешу.
Виправлення не вимагало подвигів. Вони очистили CDN-кеш для уражених шляхів, вивели зі справності зламану ноду, коректно перевстановили плагін і лише потім повернули ноду в пул.
Але висновок залишився: коли ви бачите загальне повідомлення, не маєте права припускати, де воно згенероване. Спочатку перевіряйте шар.
Післяінцидентне завдання було простим і ефективним: робити 503 відповіді некешованими на edge, хіба що це явно дозволено, і додати перевірку «обхід origin» у runbook для виклику.
Міні-історія 2: Оптимізація, що зіграла проти них
Інша організація вирішила «прискорити» WordPress, перемістивши wp-content на мережеве сховище, щоб кілька веб-хостів ділилися uploads і плагінами. Під нормальним навантаженням це працювало.
Оновлення, однак, стали рулеткою.
В день оновлення zip плагіна завантажувався, починалося розпакування, а потім файловий блок зупинявся на кілька секунд. Спайки латентності NFS означали, що перейменування директорій та операції метаданих займали стільки часу, що PHP-запити впадали по таймауту.
WordPress помирав посеред оновлення, лишаючи .maintenance і каталог плагіна напівпереміщеним.
Команда намагалася компенсувати, збільшуючи PHP-таймаути і додаючи повтори. Це зробило сайт «більш толерантним», але також зробило збої повільнішими і важчими для виявлення. Користувачі довше сиділи в режимі обслуговування. Викликали — довше сиділи на нарадах. Усі програли.
Нудне виправлення полягало в тому, щоб перестати оптимізувати не те: вони перемістили код плагінів/тем назад на локальний диск кожної ноди і лишили uploads на спільному сховищі. Деплои синхронізували плагінні зміни через артефакти.
Оновлення перестали застрягати, бо критичний шлях оновлення більше не залежав від повільних метаданичних викликів мережевого файлового сховища.
Коли кажуть «сховище повільне», зазвичай мають на увазі «повільні метаданичні операції». Оновлення WordPress — це здебільшого операції з метаданими в костюмі zip-файлу.
Міні-історія 3: Нудна, але правильна практика, що врятувала день
Компанія з сильно кастомізованим WordPress дотримувалася суворого процесу релізу: спочатку staging, потім продакшн, з оновленнями через WP-CLI і реальною можливістю відкату.
Ніхто не мав права натискати «Оновити» в продакшні, що зробило адмінку трохи менш захопливою. Інтернет пережив.
Одного дня автоматичні оновлення перекладів запустили режим обслуговування ненадовго, потім сайт повернувся до норми. Через кілька хвилин моніторинг зафіксував підвищення помилок — не через режим обслуговування, а через конфлікт автозавантажувача плагіна, що проявлявся лише в певному закешованому стані.
Оскільки у них були логи, метрики і відомий робочий артефакт, вони не почали «чинити» продакшн вручну. Вони відкотилися до попереднього артефакту на всіх нодах, відключили канал автоматичних оновлень, який ввів зміну, і послідовно відновили сервіс.
Потім повторили проблему в staging і виправили її належним чином.
Їхній великий успіх полягав не в хитрій команді. Він полягав у дисципліні: єдине джерело правди для коду, відтворювані деплои і можливість відкотитися без ручного правлення напівзаповнених каталогів плагінів.
Жарт №2: Найнадійніша стратегія оновлень WordPress досі — «не робіть живу операцію», що, до речі, і моя порада для більшості хобі.
Типові помилки: симптом → корінна причина → виправлення
Тут ви припиняєте здогадки. Зіставте свій симптом з ймовірною причиною і зробіть конкретне виправлення.
1) Симптом: банер обслуговування стоїть годинами; сайт повертає 503
- Корінна причина: Застарілий файл
.maintenance, що лишився після перерваного оновлення. - Виправлення: Видаліть
.maintenanceу корені WordPress; потім перевірте цілісність плагінів/тем/ядра й логи, щоб знайти, що зірвалося.
2) Симптом: банер зник після видалення .maintenance, але тепер білий екран (500)
- Корінна причина: Часткове оновлення плагіна/теми, що спричинило фатальну помилку PHP.
- Виправлення: Перегляньте логи PHP, потім перевстановіть або відновіть зламаний плагін/тему. Використовуйте WP-CLI де можливо. Не «видаляйте випадкові папки, поки не запрацює».
3) Симптом: деякі користувачі бачать банер, інші — ні
- Корінна причина: CDN або зворотний проксі кешує відповідь обслуговування; або кілька origin-нодів у неконсистентному стані.
- Виправлення: Перевірте origin напряму, очистіть кеші і переконайтеся, що всі ноди мають однаковий код. Виведіть з ладу пошкоджені ноди.
4) Симптом: оновлення завжди падають і режим обслуговування часто застрягає
- Корінна причина: Невідповідність прав/володіння; PHP-користувач не може перейменувати/записати директорії.
- Виправлення: Визначте модель: або дозволити WordPress писати (правка володіння/ACL), або вимкнути оновлення через адмінку і робити деплои через CI/CD.
5) Симптом: оновлення починається, потім зависає; навантаження на сервер росте; I/O wait зростає
- Корінна причина: Повільне сховище або затримки мережевого файлового сховища під час розпакування/перейменувань.
- Виправлення: Перемістіть код на локальний диск, лишіть спільне сховище тільки для uploads, або перестройте оновлення як артефактні деплои. Дослідіть вузькі місця I/O і використання інодів.
6) Симптом: повідомлення про обслуговування постійно з’являється одразу після видалення
- Корінна причина: Інший процес оновлення періодично зазнає невдачі і створює
.maintenanceповторно, часто через автооновлення або cron. - Виправлення: Тимчасово вимкніть автооновлення, перевірте cron-джоби і знайдіть компонент, що зазнає невдачі, через логи і вихід WP-CLI.
7) Симптом: лише /wp-admin показує проблеми; фронтенд виглядає нормально
- Корінна причина: Точка оновлення на боці адмінки падає; це може бути через таймаути PHP, WAF-правила, що блокують POST, або плагін, який завантажується тільки в адмінці.
- Виправлення: Перевірте логи WAF, таймаути PHP і помилки плагінів, що працюють в адмінці. Оновлюйте через WP-CLI, щоб обійти таймаути браузера.
Контрольні списки / покроковий план
Чекліст аварійного відновлення (поверніть користувачів)
- Підтвердіть шар: Чи відповідає повідомлення про обслуговування origin або кеш upstream?
- Перевірте
.maintenance: Якщо він є і застарів — видаліть. - Повторна перевірка: Підтвердіть HTTP 200 і що головна сторінка рендериться.
- Перевірте логи: Шукайте фатали PHP і помилки прав під час вікна оновлення.
- Виправте зламаний компонент: Перевстановіть/відновіть плагін/тему/ядро за потреби.
- Стабілізуйте сховище: Переконайтеся, що місця на диску і іноди не на межі.
- Очистіть кеші: Об’єктний кеш + кеш сторінок + кеш CDN за потреби.
- Перевірте критичні шляхи: Вхід, адмін-панель і будь-які бізнес-процеси, що приносять дохід.
План контрольованого відновлення (коли підозрюєте часткові оновлення)
- Поставте сайт у навмисний режим обслуговування (опціонально): Якщо у вас є реальний плагін/сторінка обслуговування, використайте його замість хаосу навколо
.maintenance. - Визначте точне зламане оновлення: Використайте списки WP-CLI і часові мітки в логах.
- Відкат або чиста перевстановлення: Замініть цілі каталоги плагінів/тем; не намагайтесь латати відсутні файли вручну.
- Перевірте контрольні суми ядра: Підтвердіть основну цілісність перед звинуваченням у всьому іншому.
- Перезапустіть оновлення по одному: Спостерігайте логи під час кожного оновлення.
- Документуйте корінну причину: Диск, іноди, права, кешування або модель процесу — виберіть одну основну і виправте її.
Чекліст операційної моделі (виберіть стратегію)
Тут команди припиняють наступати на одні й ті ж граблі. Визначте, як відбуваються оновлення у вашому середовищі:
- Модель A: WordPress самооновлюється на сервері. Тоді потрібно забезпечити правильне володіння/ACL, достатній диск/іноди і безпечні правила кешування.
- Модель B: Іммутабельні деплои (рекомендовано для серйозного продакшну). Тоді вимкніть оновлення через адмінку, збирайте версовані артефакти в CI і розгортайте атомарно з можливістю відкату.
Модель A може працювати. Модель B краще масштабується. Змішування їх породжує інциденти, в яких всі мають рацію, а сайт все одно недоступний.
Запобігання: припиніть переживати цей інцидент знову
Перестаньте робити масове «Оновити все» в продакшні
Оновлюйте по одному компоненту. Слідкуйте за системою. Якщо впаде — ви знатимете, що саме впало.
«Оновити все» ефективно для людей, але жорстоко для налагодження.
Надайте оновленням необхідні ресурси
Оновлення не вимагають великої обчислювальної потужності, але вони інтенсивно працюють з файловою системою. Це означає:
- Тримайте справжній запас місця на диску (не «99% зайнято, але технічно ще нормально»).
- Слідкуйте за інодами, особливо на малих кореневих файлових системах і в шарах контейнерного оверлею.
- Уникайте виконання коду плагінів/тем на повільних мережевих файлових системах, якщо можете.
Налаштуйте кешування так, щоб воно відображало реальність
Якщо ваш edge кешує 503 надовго, ви обираєте «швидші простої». Іноді це виправдано. Частіше — це просто cargo-cult конфігурація.
Переконайтеся, що CDN/проксі трактують відповіді обслуговування як некешовані, якщо ви цього не хочете спеціально.
Логируйте й спостерігайте оновлення серйозно
WordPress — це прикладне ПЗ. Оновлення — це деплой. Ставтеся до них відповідно:
- Централізовано збирайте помилки PHP.
- Фіксуйте час оновлень (навіть простий журнал змін допомагає).
- Налаштуйте алерти на стійкі 503 та різкий ріст помилок у вікні оновлення.
Використовуйте WP-CLI для оновлень, особливо на навантажених сайтах
Оновлення через браузер крихкі: вони залежать від одного HTTP-запиту, що має протриматися достатньо довго. WP-CLI — керованіші, легше логуються й виконуються в сесії, яка не зникне, коли ваш ноутбук втратить Wi‑Fi.
Цитата, щоб не забувати
«Сподівання — не стратегія.» — генерал Гордон Р. Салліван
Немає потреби ставати філософом. Просто припиніть покладатись на «зазвичай воно само очищається» як на операційну стратегію.
FAQ
1) Чи безпечно видаляти файл .maintenance?
Зазвичай так — якщо оновлення не виконується активно. Видалення знімає блокування. Ризик у тому, що ви піддаєте користувачів напівоновленому сайту. Якщо підозрюєте часткові оновлення, видаліть блокування, а потім негайно перевірте логи і перевстановіть зламані компоненти.
2) Де саме знаходиться .maintenance?
У кореневому каталозі WordPress — зазвичай у тому самому каталозі, що містить wp-config.php, wp-admin і wp-includes. Не в wp-content.
3) Чому WordPress повертає 503 під час обслуговування?
Тому що це правильний сигнал для клієнтів і кешів: «сервіс тимчасово недоступний». Проблема — коли кеші обробляють це неправильно або коли «тимчасово» стає «доки людина не прийде».
4) Файл зник, але я досі бачу повідомлення про обслуговування. Що робити?
Спочатку підозрюйте кешування. Перевірте origin напряму і очистіть CDN/зворотний проксі/кеш сторінок. Якщо origin повертає 200, але edge все ще віддає 503 — це вже не WordPress, а стан кешу.
5) Чи може плагін викликати режим обслуговування без мого оновлення?
Так. Автооновлення, оновлення перекладів і деякі механізми хостера можуть запускати режим обслуговування. Також плагін може зламати процес оновлення, залишивши блокування, навіть якщо тригер був інший.
6) Чи варто відключити автоматичні оновлення, щоб запобігти цьому?
Не відключайте оновлення безпеки лише тому, що оновлення одного разу зашкодило. Краще усунути основні причини: права, диск/іноди і безпечний процес оновлення (WP-CLI, staging, артефакти).
Вимкнення автооновлень обмінює інцидент доступності на інцидент безпеки. Це невигідна угода.
7) Чому це відбувається частіше на спільному хостингу?
Спільний хостинг часто має обмежений диск, низький I/O, дивні права і таймаути PHP. Механізм оновлення WordPress припускає, що він може швидко записувати і перейменовувати файли. На спільному хостингу це припущення часто невірне.
8) Як запобігти частковим оновленням плагінів?
Використовуйте послідовну модель деплою. Віддавайте перевагу артефактним деплоям або принаймні WP-CLI оновленням, що виконуються в стабільній сесії. Забезпечте достатній запас диску/інодів і правильне володіння/ACL. Уникайте оновлень у піковий трафік, де ймовірність таймаутів вища.
9) Чи погіршує ситуацію запуск WordPress на NFS/EFS?
Може. Оновлення передбачають багато дрібних файлових операцій (інтенсивні операції метаданих). Мережеві файлові системи можуть створювати стрибки латентності, що викликають таймаути і часткові переміщення. Якщо ви змушені використовувати спільне сховище, тримайте uploads там, а код розгортайте локально.
10) Яке найчистіше «корпоративне» вирішення?
Вимкніть оновлення через адмінку в продакшні, збирайте версовані артефакти в CI, розгортайте атомарно і тримайте шлях відкату. Нехай WordPress буде застосунком, а не інтерактивним редактором файлів.
Висновок: наступні кроки, які дійсно допомагають
Якщо ви застрягли на «Короткочасне відключення через планове обслуговування», ваш найшвидший виграш майже завжди такий:
підтвердіть origin проти кешу, видаліть .maintenance, якщо він застарів, а потім перевірте, що оновлення зламало.
Після цього усуньте реальну причину: права, диск/іноди, повільне сховище або процес оновлення, що залежить від крихкого браузерного запиту.
Практичні наступні кроки:
- Внесіть «перевірити
.maintenance+ перевірити диск/іноди + перевірити логи» у ваш on-call runbook. - Виберіть модель оновлень (самооновлення або іммутабельний деплой) і дотримуйтеся її.
- Зробіть 503 відповіді некешованими, якщо ви не хочете кешованих простоїв.
- Використовуйте WP-CLI для контрольованих, логованих оновлень — по одному компоненту за раз.