К основному содержимому

systemd: создание unit-файла для автозапуска службы на Linux

VDS / VPS · 19.04.2026 · 3 мин чтения
Иллюстрация к статье «systemd: создание unit-файла для автозапуска службы на Linux»

systemd — система инициализации и управления службами в современных Linux-дистрибутивах (Ubuntu 16.04+, Debian 8+, CentOS 7+). Unit-файл описывает, как запускать и останавливать сервис.

Минимальный unit-файл

# /etc/systemd/system/myapp.service

[Unit]
Description=My Application
After=network.target

[Service]
ExecStart=/usr/bin/node /opt/myapp/app.js
WorkingDirectory=/opt/myapp
User=www-data
Restart=on-failure

[Install]
WantedBy=multi-user.target

Ключевые директивы [Unit]

ДирективаЗначение
DescriptionОписание сервиса
After=network.targetЗапускать после инициализации сети
After=mysql.serviceЗапускать после MySQL
Requires=docker.serviceЖёсткая зависимость
Wants=redis.serviceМягкая зависимость

Ключевые директивы [Service]

[Service]
Type=simple           # Тип: simple, forking, oneshot, notify
ExecStart=/path/cmd   # Команда запуска
ExecStop=/path/stop   # Команда остановки (опционально)
ExecReload=/bin/kill -HUP $MAINPID  # Перезагрузка конфига
WorkingDirectory=/app # Рабочая директория
User=appuser          # Запускать от имени пользователя
Group=appgroup        # Группа
Environment=NODE_ENV=production  # Переменные окружения
EnvironmentFile=/etc/myapp.env   # Файл с переменными

# Политика перезапуска
Restart=always        # Всегда перезапускать
Restart=on-failure    # Только при ошибке
RestartSec=5s         # Пауза перед перезапуском

# Ограничения ресурсов
LimitNOFILE=65536     # Лимит открытых файлов
MemoryLimit=512M      # Лимит памяти

Активация и управление

# Перечитать unit-файлы
sudo systemctl daemon-reload

# Включить автозапуск
sudo systemctl enable myapp

# Запустить
sudo systemctl start myapp

# Проверить статус
sudo systemctl status myapp

# Посмотреть логи
sudo journalctl -u myapp -f

# Логи за сегодня
sudo journalctl -u myapp --since today

Пример: Python-приложение с virtualenv

>[Unit]
Description=Python Flask App
After=network.target postgresql.service

[Service]
Type=simple
User=flask
WorkingDirectory=/opt/flask_app
Environment=FLASK_ENV=production
ExecStart=/opt/flask_app/venv/bin/gunicorn     --workers 4     --bind 0.0.0.0:8000     app:application
Restart=on-failure
RestartSec=10

[Install]
WantedBy=multi-user.target
💡 Хранение секретов: Не помещайте пароли в unit-файл — он доступен всем. Используйте EnvironmentFile=/etc/myapp.env с правами 600. Ещё лучше — systemd credentials или HashiCorp Vault.

Типичные ошибки systemd unit-файлов

СообщениеПричина
Failed to start myapp.service: Unit not foundФайл лежит не в /etc/systemd/system/, либо после его создания забыли выполнить systemctl daemon-reload
Main process exited, code=exited, status=203/EXECПуть в ExecStart указан неверно, либо у файла нет прав на выполнение — нужен chmod +x
Failed with result 'exit-code' сразу после стартаПриложение падает без переменной окружения, которая была в .bashrc — systemd не читает пользовательские shell-конфиги
Start request repeated too quicklyRestart=always вместе с постоянным падением сервиса превышает лимит StartLimitBurst за StartLimitIntervalSec; systemd временно блокирует автозапуск
Failed to determine user credentials: No such processПользователь, указанный в User=, не существует в системе — опечатка в имени или пользователь не был создан заранее

Когда systemd unit не подходит

  • Нужен запуск процесса без root-доступа к серверу — создание файла в /etc/systemd/system требует привилегий, недоступных на большинстве shared-хостингов, там для регулярных задач есть только cron
  • Приложение должно масштабироваться на несколько инстансов с балансировкой нагрузки — один unit-файл поднимает один процесс, для нескольких копий нужны юниты-шаблоны (@.service) или отдельный оркестратор вроде Docker Compose
  • Сервис работает внутри минимального Docker-контейнера — там systemd обычно не запущен как PID 1, нужен другой supervisor (tini, s6, встроенный healthcheck)
  • Нужна кроссплатформенная служба одним конфигом для Linux и Windows — systemd специфичен для Linux, для Windows потребуется отдельный механизм вроде NSSM

Проверка результата

Мало убедиться, что сервис запустился один раз — важно проверить, что он переживает падение процесса и не упирается в лимиты памяти. Разбор системных логов есть в статье про journalctl и rsyslog, а частую причину внезапной остановки процессов — в статье про OOM Killer в Linux.

# Убедиться, что сервис реально перезапускается после падения
sudo systemctl kill -s SIGKILL myapp
sleep 3
sudo systemctl status myapp | grep Active

# Проверить, не упирается ли процесс в лимит памяти
journalctl -u myapp | grep -i "oom\|killed"
Статья помогла?
← Назад в базу знаний Задать вопрос поддержке