← Весь справочник

supervisor: supervisord и supervisorctl

Менеджер процессов supervisor — секция [program:…], автоперезапуск, логи и команды supervisorctl

Supervisor держит запущенными долгоживущие программы: веб-приложения, воркеры очередей, ботов. Демон supervisord запускает программы, описанные в конфигурации, перезапускает упавшие и собирает их вывод в логи. supervisorctl — пульт управления: показать статус, остановить, запустить, перечитать конфигурацию. Supervisor часто используют там, где нет systemd, — например, в контейнерах. Пакет supervisor написан на Python.

Синтаксис

supervisord [-c файл] [-n]                 # запустить демон; -n — не уходить в фон
supervisorctl [-c файл] команда [имя…]     # одна команда
supervisorctl                              # интерактивная консоль: supervisor> status

Где лежат файлы (Ubuntu)

ПутьЧто это
/etc/supervisor/supervisord.confглавная конфигурация; подключает conf.d/*.conf
/etc/supervisor/conf.d/имя.confконфигурации программ — по файлу на программу
/var/log/supervisor/supervisord.logлог самого демона: старты, падения, перезапуски
/var/log/supervisor/логи программ по умолчанию (имя-stdout---supervisor-XXXX.log)
/var/run/supervisor.sockсокет, через который supervisorctl говорит с демоном

Секция [program:имя]

КлючЧто задаётПо умолчанию
commandкоманда запуска; программа должна работать на переднем планеобязателен
directoryрабочий каталог перед запускомне меняется
userот какого пользователя запускать (демон должен работать от root)пользователь демона
environmentпеременные: KEY="value",KEY2="value2"—
autostartзапускать при старте supervisordtrue
autorestartперезапускать после выхода: true, false, unexpected (только при коде не из exitcodes)unexpected
exitcodes«ожидаемые» коды выхода для autorestart=unexpected0
startsecsсколько секунд программа должна проработать, чтобы старт считался успешным1
startretriesсколько раз пытаться запустить, прежде чем сдаться (FATAL)3
stopsignalсигнал для остановки: TERM, INT, QUIT, HUP, KILL, USR1, USR2TERM
stopwaitsecsсколько ждать после stopsignal, прежде чем послать SIGKILL10
stopasgroup / killasgroupслать сигнал всей группе процессов — чтобы не остались потомкиfalse
stdout_logfile / stderr_logfileкуда писать вывод; AUTO — в /var/log/supervisor/, NONE — никудаAUTO
redirect_stderrписать stderr в тот же лог, что stdoutfalse
stdout_logfile_maxbytes / _backupsразмер лога до ротации и число старых копий50MB / 10
numprocsсколько копий запустить; нужен process_name с %(process_num)1
process_nameимя процесса, например %(program_name)s_%(process_num)02d%(program_name)s
priorityпорядок запуска и остановки: меньше — раньше стартует999

Несколько программ объединяют в [group:имя] с ключом programs=a,b — тогда ими управляют как имя:*.

Команды supervisorctl

КомандаЧто делает
status [имя…]состояние программ: имя, статус, PID, время работы
start имя / stop имязапустить / остановить; all — все, группа:* — всю группу
restart имяостановить и запустить; конфигурацию не перечитывает
rereadперечитать конфигурацию и показать, что изменилось (available, changed, disappeared), ничего не применяя
update [группа]применить изменения: запустить новые программы, перезапустить изменённые, убрать удалённые
tail [-f] [-N] имя [stdout|stderr]показать конец лога программы; -f — следить, -1600 — последние 1600 байт
maintail [-f]конец лога самого supervisord
pid [имя]PID программы; без имени — PID демона
signal СИГНАЛ имяпослать сигнал программе: signal HUP web — например, перечитать конфиг
availвсе программы из конфигурации и в каком они состоянии
add / remove имядобавить / убрать одну группу после reread
clear имяочистить лог программы
fg имяподключиться к программе на переднем плане (выход — Ctrl-C)
reloadперезапустить сам supervisord — с перезапуском всех программ
shutdownостановить supervisord и все программы
help [команда]справка

Состояния в status

СостояниеЧто значит
RUNNINGработает (прожила дольше startsecs)
STARTINGзапускается, ещё не прошло startsecs
STOPPEDостановлена вручную или не запускалась (autostart=false)
STOPPINGостанавливается
BACKOFFупала при старте, supervisor пробует снова
EXITEDзавершилась после успешного старта и не перезапускается
FATALне удалось запустить за startretries попыток — смотри логи
UNKNOWNошибка в самом supervisor

supervisorctl status возвращает код 3, если хотя бы одна программа не в состоянии RUNNING, и 4, если не удаётся связаться с демоном.

Примеры

# описать программу
cat > /etc/supervisor/conf.d/web.conf <<'EOF'
[program:web]
command=python3 -m http.server 8000
directory=/tmp
user=nobody
autostart=true
autorestart=true
environment=APP_ENV="prod"
stdout_logfile=/var/log/web.out.log
redirect_stderr=true
EOF

# запустить демон (там, где он не стартует как служба)
supervisord -c /etc/supervisor/supervisord.conf

# применить новую или изменённую конфигурацию
supervisorctl reread
supervisorctl update

# состояние всех программ и одной
supervisorctl status
supervisorctl status web

# перезапуск и просмотр лога
supervisorctl restart web
supervisorctl tail -2000 web
supervisorctl tail -f web stderr

# несколько воркеров одной программы
cat > /etc/supervisor/conf.d/worker.conf <<'EOF'
[program:worker]
command=sleep 1000
numprocs=2
process_name=%(program_name)s_%(process_num)02d
EOF
supervisorctl reread && supervisorctl update
supervisorctl stop 'worker:*'

# почему программа в FATAL
supervisorctl tail web stderr
supervisorctl maintail | tail -20

Подводные камни

  • restart не видит правок конфигурации. После изменения .conf нужны supervisorctl reread и supervisorctl update — update сам перезапустит изменённую программу.
  • Программа должна работать на переднем плане. Если command уходит в фон (демонизируется, как nginx без daemon off;), supervisor видит мгновенный выход, перезапускает её снова и снова, а в итоге ставит FATAL. Ищи у программы опцию «не уходить в фон» (-f, --foreground, daemon off;).
  • FATAL с Exited too quickly — программа завершилась раньше startsecs. Причина обычно в логах программы (tail имя stderr): опечатка в пути, нет прав, не задана переменная окружения.
  • supervisorctl без демона не работает. Ошибка unix:///var/run/supervisor.sock no such file значит, что supervisord не запущен или слушает другой сокет.
  • environment не раскрывает $VAR как оболочка. Значения с запятыми и спецсимволами бери в кавычки; переменные окружения демона подставляются через %(ENV_ИМЯ)s.
  • tail -N — это байты, а не строки. supervisorctl tail -100 web покажет последние 100 байт.
  • Остановка убивает только главный процесс. Если command — скрипт-обёртка, его потомки могут остаться жить. Используй exec в обёртке или stopasgroup=true и killasgroup=true.
  • Состояние группы указывается со звёздочкой: stop 'worker:*'. Звёздочку бери в кавычки, иначе оболочка может раскрыть её как шаблон файлов.

См. также

service · ps · kill · background · logrotate · tmux