Linux

Создаем systemd-сервис: полное руководство по настройке автозапуска

В этом гайде вы узнаете, как создавать, настраивать и управлять службами systemd — стандартом для инициализации и управления процессами в современных дистрибутивах Linux.

Обновлено 17 февраля 2026 г.
15-30 мин
Средняя
FixPedia Team
Применимо к:Ubuntu 20.04+Debian 11+CentOS/RHEL 8+Fedora 35+

Введение / Зачем это нужно

Systemd — это система инициализации и менеджер служб, который используется по умолчанию в большинстве современных дистрибутивов Linux (Ubuntu, Fedora, Debian, CentOS). Вместо скриптов в /etc/init.d/ вы работаете с декларативными юнит-файлами (unit files). Этот подход даёт мощные возможности: управление зависимостями, параллельный запуск, автоматический перезапуск упавших процессов и централизованное логирование через journald.

В этом гайде вы научитесь создавать собственные systemd-сервисы для запуска ваших приложений, скриптов или демонов в фоне с контролем над их жизненным циклом.

Требования / Подготовка

Перед началом убедитесь, что:

  1. У вас есть доступ к терминалу Linux с правами sudo (администратора).
  2. Вы знакомы с базовыми командами редактирования файлов (nano, vim).
  3. Путь к исполняемому файлу или скрипту, который вы хотите запустить как сервис, известен и доступен.
  4. Дистрибутив использует systemd (проверить можно командой pidof systemd).

Шаг 1: Создайте юнит-файл сервиса

Все пользовательские юнит-файлы сервисов размещаются в /etc/systemd/system/. Имя файла должно заканчиваться на .service и обычно совпадает с логическим именем сервиса.

# Перейдите в системную директорию для юнитов
cd /etc/systemd/system/

# Создайте файл сервиса (замените myapp на своё имя)
sudo nano myapp.service

⚠️ Важно: Не создавайте файлы напрямую в /lib/systemd/system/ — эта директория предназначена для пакетов дистрибутива. Ваши ручные правки в /etc/systemd/system/ будут приоритетнее.


Шаг 2: Напишите конфигурацию юнит-файла

Юнит-файл состоит из нескольких секций. Вот минимальный, но рабочий шаблон:

[Unit]
Description=Мой кастомный сервис
Documentation=man:myapp(1)
After=network.target

[Service]
Type=simple
User=ваш_пользователь
Group=ваша_группа
ExecStart=/полный/путь/к/вашему/скрипту_или_бинарнику
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

Разбор секций:

  • [Unit] — метаданные и зависимости.
    • Description — краткое описание сервиса.
    • After= — указывает, что этот сервис должен запускаться после указанных. network.target — частый вариант для сетевых приложений.
    • Requires= — жёсткая зависимость (если указанный сервис упадёт, упадёт и этот).
  • [Service] — ядро конфигурации.
    • Type= — тип сервиса. simple (по умолчанию) — процесс запускается и работает в foreground. forking — для демонов, которые делают fork().
    • User= / Group= — от имени кого запускать процесс. Крайне рекомендуется не запускать всё от root.
    • ExecStart=обязательная директива. Полный путь к исполняемому файлу или скрипту. Скрипт должен быть исполняемым (chmod +x скрипт.sh).
    • Restart= — политика перезапуска. on-failure — перезапускать при ненулевом коде выхода. always — всегда.
    • RestartSec= — задержка перед перезапуском в секундах.
  • [Install] — инструкции для systemctl enable.
    • WantedBy= — определяет, в каком целевом состоянии (target) должен быть включён сервис. multi-user.target — стандартный многопользовательский режим (аналог runlevel 3/5).

💡 Совет: Для простых скриптов часто достаточно шаблона выше. Для Java-приложений или сложных сред может понадобиться EnvironmentFile= (загрузка переменных окружения из файла) или ExecStartPre= (команда перед запуском).


Шаг 3: Перезагрузите конфигурацию systemd

После сохранения файла systemd должен «увидеть» новый юнит. Выполните:

sudo systemctl daemon-reload

Эта команда заставляет systemd перечитать все юнит-файлы с диска. Без неё systemctl будет работать со старой копией конфигурации.


Шаг 4: Включите и запустите сервис

Теперь можно активировать сервис.

  1. Включите для автозапуска (создаст симлинк в /etc/systemd/system/multi-user.target.wants/):
    sudo systemctl enable myapp.service
    

    Вывод Created symlink /etc/systemd/system/multi-user.target.wants/myapp.service → /etc/systemd/system/myapp.service. означает успех.
  2. Запустите немедленно без перезагрузки:
    sudo systemctl start myapp.service
    

Шаг 5: Проверьте статус и логи

Убедитесь, что сервис работает штатно.

# Основная команда проверки
systemctl status myapp.service

Что искать в выводе:

  • Active: active (running) — сервис жив.
  • Loaded: loaded (/etc/systemd/system/myapp.service; enabled; vendor preset: enabled) — файл загружен и включён.
  • Никаких красных строк Failed или inactive (dead).

Для детального просмотра логов используйте journalctl:

# Показать все логи сервиса (с самого начала)
sudo journalctl -u myapp.service

# Отслеживать логи в реальном времени (как tail -f)
sudo journalctl -u myapp.service -f

# Показать логи за последние 10 минут
sudo journalctl -u myapp.service --since "10 minutes ago"

Возможные проблемы

1. Ошибка Failed to start... или сервис сразу падает

  • Причина: Ошибка в самом приложении/скрипте, который запускает ExecStart.
  • Решение: Запустите команду из ExecStart вручную в терминале, чтобы увидеть её вывод. Проверьте права на файл и пути к зависимым библиотекам/файлам.
  • Диагностика: journalctl -u myapp.service -n 50 --no-pager покажет последние 50 строк логов сервиса.
  • Причина: В секции [Install] отсутствует WantedBy= или RequiredBy=, либо указан неверный target.
  • Решение: Добавьте WantedBy=multi-user.target (для фоновых служб) или WantedBy=graphical.target (для GUI-приложений). Перевыполните daemon-reload и enable.

3. Сервис запускается, но не работает как ожидается (нет доступа к сети, файлам)

  • Причина: Проблема с контекстом безопасности. Сервис запускается в изолированном окружении.
  • Решение:
    • Убедитесь, что User= и Group= указаны правильно.
    • Для доступа к сетевым портам <1024 могут потребоваться дополнительные capabilities (AmbientCapabilities=CAP_NET_BIND_SERVICE) или запуск от root (не рекомендуется).
    • Проверьте, что у указанного пользователя есть права на чтение/запись в нужные директории.

4. Ошибка Dependency failed for...

  • Причина: Сервис имеет зависимость (After=, Requires=) от другой службы, которая не запустилась или не существует.
  • Решение: Проверьте статус зависимых служб (systemctl status network.target или вашей_зависимости.service). Убедитесь, что имена зависимостей написаны правильно.

Часто задаваемые вопросы

Как проверить, что сервис systemd запустился успешно?
Почему мой сервис не запускается автоматически после загрузки?
Где хранятся логи моего systemd-сервиса?
Можно ли запустить сервис от имени другого пользователя?

Полезное

Создайте юнит-файл сервиса
Напишите конфигурацию юнит-файла
Перезагрузите конфигурацию systemd
Включите и запустите сервис
Проверьте статус и логи

Эта статья помогла вам решить проблему?