systemd: управление сервисами
systemd — система инициализации Linux, управляющая службами (сервисами): запускает их при старте, перезапускает при падении, собирает логи через journald.
Зачем нужно
Без systemd приложение на сервере останавливается при закрытии SSH-сессии или перезагрузке сервера. Systemd unit-файл превращает Node.js приложение в системный сервис: автозапуск, перезапуск при падении, централизованные логи через journalctl. Это стандартный способ управления процессами без Docker.
Где используется
- Запуск Node.js / Python / Go приложения как системного сервиса
- Nginx, PostgreSQL, Redis управляются через systemd
- Cron-like задачи через systemd timers
- Мониторинг состояния процессов на сервере
Основной контент
Управление сервисами
# Основные команды
sudo systemctl start myapp # запустить
sudo systemctl stop myapp # остановить
sudo systemctl restart myapp # перезапустить
sudo systemctl reload myapp # перезагрузить конфиг (без рестарта)
sudo systemctl status myapp # статус сервиса
sudo systemctl enable myapp # автозапуск при загрузке
sudo systemctl disable myapp # отключить автозапуск
# Просмотр логов сервиса
sudo journalctl -u myapp # все логи
sudo journalctl -u myapp -f # follow (live)
sudo journalctl -u myapp --since "1 hour ago"
sudo journalctl -u myapp -n 100 # последние 100 строк
Создание unit-файла для Node.js
# /etc/systemd/system/myapp.service
[Unit]
Description=My Node.js Application
Documentation=https://github.com/myuser/myapp
After=network.target postgresql.service # запускать после сети и БД
[Service]
Type=simple
User=deploy # запускать от непривилегированного пользователя
Group=deploy
WorkingDirectory=/var/www/myapp
ExecStart=/usr/bin/node dist/index.js
ExecReload=/bin/kill -HUP $MAINPID # reload signal
# Автоматический перезапуск
Restart=on-failure
RestartSec=5s
StartLimitInterval=60s
StartLimitBurst=3 # не более 3 перезапусков за 60s
# Переменные окружения
Environment=NODE_ENV=production
Environment=PORT=3000
EnvironmentFile=/etc/myapp.env # дополнительные переменные из файла
# Логи
StandardOutput=journal
StandardError=journal
SyslogIdentifier=myapp
# Ограничения безопасности
NoNewPrivileges=true
PrivateTmp=true
[Install]
WantedBy=multi-user.target
# Активировать сервис
sudo systemctl daemon-reload # перечитать unit-файлы
sudo systemctl enable --now myapp # включить и запустить
# Проверить
sudo systemctl status myapp
Файл с переменными окружения
# /etc/myapp.env (права 600, владелец root или deploy)
DATABASE_URL=postgres://user:pass@localhost:5432/mydb
REDIS_URL=redis://localhost:6379
SECRET_KEY=supersecretkey
sudo chmod 600 /etc/myapp.env
sudo chown root:root /etc/myapp.env
systemd timers (альтернатива cron)
# /etc/systemd/system/cleanup.service
[Unit]
Description=Database cleanup job
[Service]
Type=oneshot
User=deploy
ExecStart=/usr/bin/node /var/www/myapp/scripts/cleanup.js
# /etc/systemd/system/cleanup.timer
[Unit]
Description=Run cleanup every day at 02:00
[Timer]
OnCalendar=*-*-* 02:00:00
Persistent=true # запустить если пропустили время
[Install]
WantedBy=timers.target
sudo systemctl enable --now cleanup.timer
systemctl list-timers # просмотр таймеров
Частые ошибки
- Забыть
daemon-reloadпосле изменения unit-файла — systemd использует старую версию - Запуск от root без необходимости — указывать
User=иGroup= Restart=alwaysбезStartLimitBurst— сервис перезапускается бесконечно при проблемах с конфигом- Хранить секреты в
Environment=внутри unit-файла (видны черезsystemctl show) — использоватьEnvironmentFile=с ограниченными правами