Supervisor — менеджер процесів для Linux. Його задача проста: тримати вказані тобою процеси запущеними і перезапускати їх, якщо вони впали. Supervisor може тримати запущеним будь-що, що має працювати постійно: queue workers, Horizon, Laravel Reverb (WebSockets), Node.js сервер, Go-бінарник, Python-скрипт — що завгодно.
Без Supervisor тобі довелося б або тримати відкритий термінал з queue:work (нереально на проді).
В контексті Laravel — основний юзкейс це queue workers (php artisan queue:work). Без Supervisor worker зупиниться після помилки або перезавантаження сервера, і ніхто не піднімає його знову. Supervisor вирішує цю проблему.
Що ставлять під Supervisor
- Laravel queue workers (
queue:work) - Laravel Horizon (
php artisan horizon) - Laravel Reverb / WebSocket сервер
- Node.js процеси
- Будь-який фоновий процес, що має працювати 24/7
Встановлення
Спочатку визначаємо ОС сервера — від цього залежить пакетний менеджер:
cat /etc/os-release
CentOS / AlmaLinux / CloudLinux (типово для WHM/cPanel):
yum install supervisor -y
systemctl enable supervisord
systemctl start supervisord
Ubuntu / Debian:
apt install supervisor -y
systemctl enable supervisor
systemctl start supervisor
Зверни увагу: на CentOS сервіс називається supervisord, на Ubuntu — supervisor.
Конфігурація
Конфіги лежать у /etc/supervisord.d/ (CentOS) або /etc/supervisor/conf.d/ (Ubuntu). Кожен процес — окремий .conf файл (на CentOS розширення .ini).
Базовий конфіг для Laravel queue worker
[program:shop-worker]
process_name=%(program_name)s_%(process_num)02d
command=/usr/local/bin/ea-php84 /home/username/public_html/shop/artisan queue:work redis --sleep=3 --tries=3 --max-time=3600
directory=/home/username/public_html/shop
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
user=username
numprocs=2
redirect_stderr=true
stdout_logfile=/home/username/public_html/shop/storage/logs/worker.log
stopwaitsecs=3600
Параметри конфігу
| Параметр | Опис |
|---|---|
[program:shop-worker] | Ім’я програми — використовується в командах supervisorctl |
process_name | Шаблон імені для кожного процесу при numprocs > 1 |
command | Команда запуску. Вказуємо повний шлях до PHP та artisan |
directory | Робоча директорія (cd перед запуском) |
autostart=true | Запускати при старті Supervisor |
autorestart=true | Перезапускати при падінні |
stopasgroup=true | Зупиняти разом з дочірніми процесами |
killasgroup=true | Вбивати разом з дочірніми процесами |
user | Від якого юзера запускати (cPanel-юзер акаунту) |
numprocs | Кількість паралельних воркерів |
redirect_stderr=true | Помилки пишуться в той самий лог |
stdout_logfile | Шлях до лог-файлу |
stopwaitsecs | Скільки секунд чекати завершення перед kill |
Параметри queue:work
| Прапорець | Опис |
|---|---|
--sleep=3 | Скільки секунд спати коли черга порожня |
--tries=3 | Макс. спроб обробки задачі перед failed |
--max-time=3600 | Перезапуск воркера через годину (запобігає витоку пам’яті) |
--queue=high,default,low | Пріоритет черг (зліва направо) |
--timeout=60 | Макс. час виконання одної задачі |
Нюанси WHM/cPanel
PHP-бінарник
cPanel з EasyApache використовує свій шлях до PHP — не /usr/bin/php, а /usr/local/bin/ea-php84 (або інша версія). Перевірити:
# Побачити всі доступні версії PHP на сервері
ls /usr/local/bin/ea-php*
# Або знайти конкретну
which ea-php84
User
В полі user конфігу Supervisor вказуємо cPanel-юзера акаунту (той, під яким лежать файли в /home/username/), а не root чи nobody.
Шляхи
cPanel розміщує сайти в /home/username/public_html/, а не в /var/www/. Якщо Laravel-проект лежить у піддиректорії: /home/username/public_html/shop/.
Термінал
Все виконується через SSH або WHM → Server Configuration → Terminal. WHM Terminal працює від root, тому sudo не потрібен.
Команди supervisorctl
Після створення або зміни конфігу
# Перечитати конфіги (знайде нові/змінені)
supervisorctl reread
# Застосувати зміни (запустити нові, зупинити видалені)
supervisorctl update
Важливо: reread тільки читає конфіги, але не застосовує. Завжди виконуй обидві команди послідовно.
Керування процесами
# Статус всіх процесів
supervisorctl status
# Приклад виводу:
# shop-worker:shop-worker_00 RUNNING pid 12345, uptime 2:15:30
# shop-worker:shop-worker_01 RUNNING pid 12346, uptime 2:15:30
# Керування конкретною програмою
supervisorctl start shop-worker:* # Запустити всі воркери
supervisorctl stop shop-worker:* # Зупинити всі
supervisorctl restart shop-worker:* # Перезапустити всі
# Керування конкретним процесом
supervisorctl start shop-worker:shop-worker_00
supervisorctl stop shop-worker:shop-worker_01
# Перезапустити все
supervisorctl restart all
Перегляд логів
# Лог конкретного процесу (останні рядки)
supervisorctl tail shop-worker:shop-worker_00
# В реальному часі
supervisorctl tail -f shop-worker:shop-worker_00
# Або напряму з файлу
tail -f /home/username/public_html/shop/storage/logs/worker.log
Supervisor + Horizon
Horizon — надбудова від Laravel над queue:work. Він сам керує воркерами зсередини (кількість процесів, балансування, автоскейлінг) і дає веб-дашборд на /horizon. Horizon не замінює Supervisor — вони працюють разом.
Без Horizon: Supervisor запускає кілька queue:work процесів, ти сам конфігуруєш кількість та параметри в .conf файлі.
З Horizon: Supervisor запускає один процес — php artisan horizon, а Horizon вже сам піднімає та керує потрібною кількістю воркерів.
[program:horizon]
command=/usr/local/bin/ea-php84 /home/username/public_html/shop/artisan horizon
directory=/home/username/public_html/shop
autostart=true
autorestart=true
user=username
redirect_stderr=true
stdout_logfile=/home/username/public_html/shop/storage/logs/horizon.log
stopwaitsecs=3600
Зверни увагу: numprocs немає — Horizon сам розбереться зі кількістю воркерів. Horizon потребує Redis як драйвер черги.
Після деплою нового коду
Queue workers кешують код при запуску. Після деплою потрібно їх перезапустити, щоб вони підхопили зміни:
# Без Horizon — плавний перезапуск (worker дочекає поточну задачу)
php artisan queue:restart
# З Horizon
php artisan horizon:terminate
# Supervisor автоматично перезапустить Horizon
queue:restart ставить сигнал “зупинись після поточної задачі”. Supervisor бачить що процес зупинився і піднімає новий — вже з оновленим кодом. З Horizon — horizon:terminate робить те саме, після чого Supervisor перезапускає Horizon.
Типові проблеми та дебаг
Worker одразу в FATAL або BACKOFF
# Перевірити лог
supervisorctl tail shop-worker:shop-worker_00
# Типові причини:
# - Невірний шлях до PHP або artisan
# - Немає прав на директорію (user невірний)
# - Redis не запущений (якщо драйвер redis)
# - .env відсутній або невалідний
supervisorctl: command not found
# Supervisor не встановлений
yum install supervisor -y # CentOS
apt install supervisor -y # Ubuntu
# Або сервіс не запущений
systemctl start supervisord # CentOS
systemctl start supervisor # Ubuntu
Worker працює, але задачі не обробляються
# Перевірити що Redis працює
redis-cli ping
# Має відповісти: PONG
# Перевірити що .env має правильний драйвер
grep QUEUE_CONNECTION /home/username/public_html/shop/.env
# QUEUE_CONNECTION=redis
# Перевірити що конфіг закешований з правильним .env
cd /home/username/public_html/shop
/usr/local/bin/ea-php84 artisan config:cache
Лог-файл росте безконтрольно
Supervisor не ротує логи автоматично. Додай ротацію в конфіг:
stdout_logfile_maxbytes=10MB
stdout_logfile_backups=5
Це обмежить лог до 10 МБ і зберігатиме 5 бекапів.
Повний приклад: від нуля до працюючої черги на WHM
# 1. Встановити Supervisor (WHM Terminal, від root)
yum install supervisor -y
systemctl enable supervisord
systemctl start supervisord
# 2. Перевірити шлях до PHP
ls /usr/local/bin/ea-php*
# 3. Створити конфіг
nano /etc/supervisord.d/shop-worker.ini
# 4. Вставити конфіг (замінити username та шляхи):
# [program:shop-worker]
# process_name=%(program_name)s_%(process_num)02d
# command=/usr/local/bin/ea-php84 /home/username/public_html/shop/artisan queue:work redis --sleep=3 --tries=3 --max-time=3600
# directory=/home/username/public_html/shop
# autostart=true
# autorestart=true
# stopasgroup=true
# killasgroup=true
# user=username
# numprocs=2
# redirect_stderr=true
# stdout_logfile=/home/username/public_html/shop/storage/logs/worker.log
# stdout_logfile_maxbytes=10MB
# stdout_logfile_backups=5
# stopwaitsecs=3600
# 5. Зберегти (Ctrl+O, Ctrl+X) і застосувати
supervisorctl reread
supervisorctl update
# 6. Перевірити
supervisorctl status
# shop-worker:shop-worker_00 RUNNING
# shop-worker:shop-worker_01 RUNNING
Практика
Пдивимось список всіх процесів під Supervisor в WHM.
[root@~]# supervisorctl status
laravel-horizon RUNNING pid 1358128, uptime 3 days, 10:18:23
reverb RUNNING pid 1360176, uptime 3 days, 10:18:07
sprm-worker RUNNING pid 1358130, uptime 3 days, 10:18:23
Три процеси, аптайм 3+ дні — значить стабільно, нічого не падає.
По суті бачимо класичний Laravel-стек: laravel-horizon керує чергами (і сам всередині піднімає воркери), reverb — WebSocket сервер для реалтайм подій, sprm-worker — судячи з назви, окремий queue worker для специфічних задач.
Якщо хочеш подивитися конфіги, вони мають лежати в /etc/supervisord.d/, вот например конфиг filament админки:
[root@ ~]# cat /etc/supervisord.d/sprm-worker.ini
[program:sprm-worker]
command=/opt/cpanel/ea-php83/root/usr/bin/php artisan horizon
directory=/home/****/oparamese.com
autostart=true
autorestart=true
user=****
redirect_stderr=true
stdout_logfile=/home/***/sprm-worker.log
Мы тут для нашего сайта запускаем horizon.