Содержание
Запуск nodejs приложения через systemd
У systemd много хейтеров, но чем больше я с ним встречаюсь по рутинным админским делам, тем больше он мне нравится.
Задача: запустить nodejs приложение в Debian 9 без смузи node менеджеров.
Требования:
- Чтобы рестартилось
- Чтобы был лог
- Чтобы KISS
Рабочая директория /usr/local/foobar
, имя приложения spacex.js
Вероятно когда-нибудь я попробую node менеджеры (сравнение)
service файл
Создадим systemd сервис файл spacex.service в директории /etc/systemd/system/
.
[Unit] Description=SpaceX simulator service # Запускать сервис после сервиса mysql Requires=After=mysql.service # Доки Documentation=https://elonmusk.guru [Service] ExecStart=/usr/bin/node /usr/local/foobar/spacex.js # Не всегда требуется, но лучше указать WorkingDirectory=/usr/local/foobar # Об этом чуть ниже Restart=always # Перезапустить сервис через 10 секунд RestartSec=10 # А можно даже так # RestartSec=500ms # Вести журнал в syslog StandardOutput=syslog StandardError=syslog # Идентификатор нашего сервиса SyslogIdentifier=AdventureTime #User=dx #Group=dx Environment=NODE_ENV=production PORT=3000 [Install] WantedBy=multi-user.target
Restart может принимать значения always или on-failure
На самом деле больше: https://www.freedesktop.org/software/systemd/man/systemd.service.html
Restart settings/Exit causes | no | always | on-success | on-failure | on-abnormal | on-abort | on-watchdog |
---|---|---|---|---|---|---|---|
Clean exit code or signal | X | X | |||||
Unclean exit code | X | X | |||||
Unclean signal | X | X | X | X | |||
Timeout | X | X | X | ||||
Watchdog | X | X | X | X |
Если установлено значение always, служба будет перезапущена независимо от того, была ли она завершена корректно или нет.
Далее как обычно для systemd
# systemctl daemon-reload # systemctl enable spacex.service # systemctl start spacex.service
Журналирование
Отдельно поговорим о логах.
Я решил записывать всё в отдельные лог файлы и по первому примеру из гугла сделал так
StandardOutput=file:/var/log/adventure_time.log StandardError=file:/var/log/adventure_time_error.log
Оказалось, что нужен systemd поновее чем предлагает Debian 9.
# systemctl --version systemd 232
В новых версиях systemd (236+) можно использовать путь к файлу. В версии 240 появился новый параметр append.
systemd + rsyslog
Рабочий вариант (спасибо rsyslog wiki и webarchive). Будем отправлять stdout/stderr в syslog с определенным идентификатором (опция SyslogIdentifier).
systemd unit service файл
StandardOutput=syslog StandardError=syslog SyslogIdentifier=AdventureTime
Подразумевается, что логами управляет rsyslog. Создаём файл /etc/rsyslog.d/at.conf
if $programname == 'AdventureTime' then /var/log/adventure_time.log & stop
Даем права на запись
chown root:adm /var/log/adventure_time.log
Перезапускаем rsyslog
# systemctl restart rsyslog
Теперь логи можно смотреть и через journalctl и в отдельном log файле.
# journalctl -u AdventureTime
Дополнительное чтиво для любопытных - The systemd house of horror. Examples of how people commonly use systemd in an egregiously wrong manner.
Обсуждение