Monit следит за тем, что службы работают, и поднимает их, когда они падают. Первый вопрос, который здесь уместен: зачем это, если systemd умеет то же самое одной строкой Restart=always?

Ответ определяет всю настройку. systemd видит, что процесс завершился, и запускает его заново. Он не знает, отвечает ли служба на запросы. PHP-FPM, упёршийся в лимит процессов, для systemd жив и здоров, а сайт при этом отдаёт 502. MySQL, у которого кончилось место, продолжает работать процессом и не выполняет ни одного запроса. Monit проверяет не факт существования процесса, а его поведение: отвечает ли порт, что возвращает HTTP-запрос, сколько занято памяти.

Отсюда правило: systemd оставляем как есть, а Monit добавляем ради функциональных проверок. Дублировать перезапуск упавшего процесса смысла нет.

Настройка

sudo apt install monit

Основной файл — /etc/monit/monitrc, свои проверки кладутся отдельными файлами в /etc/monit/conf.d/. Начало обычное:

set daemon 60
set logfile /var/log/monit.log
set mailserver localhost
set alert admin@example.com

Опрос раз в минуту — разумный баланс. Более частый добавляет нагрузку и повышает риск ложного перезапуска на секундной задержке.

Веб-интерфейс: только локально

У Monit есть встроенная веб-страница, и по умолчанию её включают примерно так, как показано в первом попавшемся руководстве, — на всех адресах. Получается панель управления службами сервера, доступная из интернета. Правильный вариант:

set httpd port 2812 and
    use address localhost
    allow localhost
    allow admin:'длинный-пароль'

Доступ снаружи — через SSH-туннель:

ssh -L 2812:localhost:2812 user@203.0.113.25

После этого страница открывается на своём компьютере по адресу localhost:2812, и наружу ничего не торчит.

Проверки, которые имеют смысл

Веб-сервер — не по факту процесса, а по ответу:

check process nginx with pidfile /run/nginx.pid
    start program = "/bin/systemctl start nginx"
    stop program  = "/bin/systemctl stop nginx"
    if failed host 127.0.0.1 port 80 protocol http
        request "/" status = 200
        for 3 cycles then restart
    if 3 restarts within 10 cycles then unmonitor

Три строки здесь важнее остальных.

protocol http ... status = 200 — это и есть проверка, ради которой всё затевалось: сервер обязан вернуть страницу, а не просто держать открытый порт.

for 3 cycles — не реагировать на единичный сбой. Без этого Monit перезапустит службу из-за одного медленного ответа под нагрузкой, чем только ухудшит положение.

if 3 restarts within 10 cycles then unmonitor — обязательная строка. Если служба не поднимается из-за ошибки в конфигурации, Monit будет перезапускать её бесконечно, добавляя нагрузку и заполняя логи. Эта строка означает: три неудачные попытки — прекратить и оставить сообщение. Дальше нужен человек, автоматика уже не поможет.

Место на диске проверяется без всякой автоматики, просто сообщением:

check filesystem rootfs with path /
    if space usage > 85% then alert
    if inode usage > 85% then alert

Строка про inode нужна отдельно: они кончаются независимо от места, и без неё эта ситуация останется незамеченной.

Проверка конфигурации

sudo monit -t
sudo systemctl reload monit
sudo monit summary
sudo monit status

monit -t проверяет синтаксис до применения. monit summary даёт короткую таблицу состояний — с неё стоит начинать разбор любой проблемы.

И проверьте отправку почты. Monit сообщает о событиях письмом, и если отправка не настроена, оповещения не будет — служба перезапустится, вы об этом не узнаете, а именно повторяющиеся перезапуски и есть главный сигнал. Смотреть их можно и в логе: /var/log/monit.log.

Чего Monit не делает

Он не устраняет причину. Перезапуск — это отсрочка, и постоянно перезапускаемая служба означает, что где-то не хватает памяти, кончается место или течёт приложение. Ценность инструмента не в самом перезапуске, а в счётчике: три перезапуска nginx за сутки — это диагноз, который иначе остался бы незамеченным, потому что сайт всё это время работал.

Поэтому смотреть надо не на текущее состояние (оно почти всегда зелёное), а на историю: сколько раз за неделю что-то поднималось само. Как это выглядит на одной странице — на демо ниже.