☰
WORDPRESS / PRACTICE

Як надійно запускати WP-Cron через системний cron

Як надійно запускати WP-Cron через системний cron

WP-Cron у WordPress працює не так, як системний cron на сервері. За замовчуванням заплановані події перевіряються під час завантаження сторінок, тому фактичний час запуску залежить від відвідуваності сайту.

На маловідвідуваному сайті листи, резервні операції або очищення кешу можуть виконуватися із затримкою. На навантаженому ресурсі кілька HTTP-запитів, навпаки, здатні майже одночасно ініціювати однакові або важкі задачі. Надійніша схема — вимкнути автоматичний запуск WP-Cron під час відвідувань і запускати чергу через системний cron за допомогою WP-CLI.

Чому стандартний WP-Cron може пропускати або відкладати задачі

WordPress зберігає заплановані події та перевіряє їх, коли хтось відкриває сторінку. Якщо сайт кілька годин не має відвідувачів, подія не обов’язково виконається у запланований момент. Вона буде оброблена під час наступного відповідного запуску.

Механізм також створює додаткові HTTP-запити до WordPress. Якщо одночасно відкривається багато сторінок, кілька процесів можуть спробувати запустити планувальник. WordPress має захист від частини повторних запусків, але покладатися лише на нього для важких або критичних задач не варто.

Системний cron працює незалежно від трафіку. Він запускає WP-CLI за розкладом, а команда перевіряє та виконує події, термін яких уже настав. Це дає передбачуваний час запуску й спрощує пошук помилок у логах.

  • низька відвідуваність не затримує заплановані події;
  • зменшується кількість фонових запусків через звичайні HTTP-запити;
  • можна централізовано перевіряти результат виконання команд;
  • системний cron можна поєднати з блокуванням паралельних процесів.

Що потрібно підготувати перед налаштуванням

Для цієї схеми потрібен доступ до сервера через SSH або інший спосіб керування системним cron. Також потрібні встановлені PHP і WP-CLI, доступні користувачу, від імені якого буде виконуватися команда.

Команду слід запускати від користувача вебсервера або власника файлів WordPress. Не використовуйте root без необхідності: це може створити файли з неправильним власником і підвищити наслідки помилки в команді.

Заздалегідь визначте точний шлях до сайту, наприклад `/var/www/site`, і перевірте, де розташований виконуваний файл WP-CLI. У cron краще використовувати абсолютні шляхи, оскільки середовище системного cron зазвичай має обмежений PATH.

  • коректний шлях до каталогу з `wp-config.php`;
  • робоча команда `wp` або її абсолютний шлях, наприклад `/usr/local/bin/wp`;
  • права користувача на файли WordPress і доступ до бази даних;
  • наявність утиліти `flock`, якщо потрібно заборонити паралельні запуски.
cd /var/www/site
wp --info
wp core is-installed

Вимкніть запуск WP-Cron під час завантаження сторінок

Відкрийте `wp-config.php` і додайте константу до завантаження файлу `wp-settings.php`. Найчастіше її розміщують поруч з іншими налаштуваннями WordPress, до рядка, який повідомляє не змінювати подальший вміст файлу.

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

  • зробіть резервну копію `wp-config.php` перед редагуванням;
  • переконайтеся, що константа не оголошена повторно з іншим значенням;
  • після зміни перевірте, що сайт і WP-CLI коректно підключаються до бази даних.
define('DISABLE_WP_CRON', true);

Додайте системний cron через WP-CLI

Відкрийте crontab потрібного користувача командою `crontab -e`. Запуск раз на хвилину підходить для більшості сайтів, яким потрібне регулярне виконання подій. Якщо для вашого проєкту достатньо меншої частоти, інтервал можна збільшити.

Параметр `--due-now` наказує WP-CLI виконати події, термін яких уже настав. `--path` вказує каталог конкретного WordPress-сайту, щоб команда не залежала від поточного робочого каталогу.

Обгортка `flock -n` створює неблокувальний lock-файл. Якщо попередній запуск ще триває, новий процес одразу завершиться, а не почне обробляти чергу паралельно.

  • використовуйте окремий lock-файл для кожного сайту;
  • перевірте, що користувач cron може створити та змінювати цей файл;
  • за потреби вкажіть абсолютний шлях до `wp`, а не лише `wp`.
* * * * * flock -n /tmp/site-wp-cron.lock /usr/local/bin/wp cron event run --due-now --path=/var/www/site

Варіант із журналом виконання

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

Перенаправлення `2>&1` додає до того самого файлу повідомлення про помилки. Лог потрібно періодично обмежувати або очищати, щоб він не заповнив дисковий простір.

  • зберігайте лог у каталозі, доступному користувачу сайту;
  • не записуйте в лог конфіденційні змінні середовища або паролі;
  • після завершення діагностики залишайте лише потрібний рівень журналювання.
* * * * * flock -n /tmp/site-wp-cron.lock /usr/local/bin/wp cron event run --due-now --path=/var/www/site >> /home/site/logs/wp-cron.log 2>&1

Перевірте чергу подій і перший запуск

Після додавання правила не чекайте навмання. Спочатку запустіть ту саму команду вручну від імені користувача, під яким працюватиме cron. Так можна відразу побачити помилки доступу, неправильний шлях до сайту, проблеми з PHP або підключенням до бази даних.

Для перегляду зареєстрованих подій використовуйте список WP-CLI. Він допомагає побачити назву hook, наступний час запуску, повторюваність і поточний стан черги.

  • перевірте, чи є події зі статусом, термін яких уже настав;
  • після ручного запуску повторіть список і переконайтеся, що час наступного виконання змінився;
  • перегляньте PHP error log і лог вебсервера, якщо обробник завершується помилкою;
  • переконайтеся, що системний cron справді завантажив нове правило.
wp cron event list --path=/var/www/site
wp cron event run --due-now --path=/var/www/site
crontab -l

Типові помилки під час налаштування

Найпоширеніша помилка — додати `DISABLE_WP_CRON`, але не налаштувати заміну. У такому разі черга накопичується, а фонові задачі не запускаються взагалі.

Інша проблема — запуск cron від root, коли вебсервер працює від іншого користувача. WP-CLI або плагіни можуть створити нові файли з власником root, після чого WordPress втратить можливість їх змінювати.

Також часто використовують відносний шлях до `wp`, сайту або лог-файлу. У cron це може не працювати через інше робоче середовище. Застосовуйте абсолютні шляхи та перевіряйте команду саме в контексті потрібного користувача.

  • не запускайте одночасно старий HTTP-механізм і системний cron без розуміння наслідків;
  • не видаляйте lock-файл під час активного процесу без перевірки — це може дозволити паралельний запуск;
  • не використовуйте один lock-файл для кількох незалежних сайтів;
  • не ігноруйте помилки WP-CLI, навіть якщо cron формально завершується;
  • для multisite за потреби вказуйте правильний сайт через параметр `--url`.

Коли системний cron не вирішує проблему повністю

Перехід на системний cron контролює момент запуску, але не виправляє помилки самих обробників. Якщо плагін падає через ліміт пам’яті, заблоковану таблицю, недоступний зовнішній API або неправильну логіку повторних спроб, проблема залишиться.

Для важких задач важливо перевірити тривалість виконання, ліміти PHP CLI та поведінку при частковому завершенні. Деякі плагіни мають власні черги або використовують Action Scheduler, тому події WP-Cron можуть лише запускати наступний етап обробки.

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

  • перевіряйте PHP error log після оновлень WordPress і плагінів;
  • контролюйте, чи не росте кількість прострочених подій;
  • перевіряйте права на lock-файл і каталог логів;
  • для критичних процесів налаштуйте сповіщення про помилки на рівні сервера або моніторингу.

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

Чи потрібно залишати WP-Cron увімкненим після налаштування системного cron?

Ні. Якщо системний cron регулярно запускає `wp cron event run --due-now`, у `wp-config.php` слід залишити `define('DISABLE_WP_CRON', true);`, щоб WordPress не створював додаткові запуски під час відвідувань.

Чому події все одно виконуються із затримкою?

Перевірте, чи працює cron, чи правильні шлях до сайту та користувач, і чи немає довгого попереднього процесу. Також подія може бути зареєстрована з власним інтервалом або блокуватися помилкою обробника.

Чи обов’язково запускати WP-Cron щохвилини?

Ні. Частота залежить від задач сайту. Щохвилинний запуск дає меншу затримку, але для проєктів без критичних подій може бути достатнім інтервал у кілька хвилин.

Що робити, якщо команда `flock` недоступна?

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

Висновок

Системний cron разом із WP-CLI робить запуск WP-Cron передбачуваним: він не залежить від трафіку, виконується від визначеного користувача та може бути захищений від паралельних процесів через `flock`.

Після налаштування важливо перевірити команду вручну, переглядати чергу через `wp cron event list` і контролювати PHP-логи. Це дозволяє не лише запускати події вчасно, а й швидко знаходити причини помилок.

← Усі матеріали WordPress