Systemctl: управление сервисами и юнитами Systemd

Запустить программу в фоне, обеспечить ее автоматический запуск после перезагрузки сервера, разобраться, почему она перестала отвечать, – все эти задачи на Линукс-сервере решает systemctl, штатный инструмент управления службами (сервисами). Он работает во всех операционных системах с systemd: Ubuntu, Debian, AlmaLinux, Rocky Linux. Логи служб показывает соседняя утилита journalctl.

В статье разберем, как устроен systemd, где используется, какие команды нужны для повседневной работы с VPS, как читать вывод systemctl status и как оформить собственное приложение как службу.

Примеры в статье приведены для Ubuntu 24.04 LTS (systemd 255). В других дистрибутивах команды те же, но могут отличаться имена служб и детали вывода. Чтобы выполнять команды, подключитесь к серверу по SSH.

Как устроен systemd

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

Процесс systemd получает номер 1 (PID 1) и работает до выключения сервера. Он монтирует файловые системы, поднимает сеть и запускает системные службы с учетом зависимостей между ними и заданного порядка. Независимые службы запускаются параллельно, поэтому система загружается быстрее.

Кроме того, systemd следит за состоянием запущенных служб и может перезапустить “упавшую” службу, если это предусмотрено ее настройками.

Что делает systemctl

systemctl – основная утилита для управления systemd. Сама она службы не запускает и не останавливает: она передает systemd запрос, например, на запуск или перезапуск службы, а действие выполняет systemd.

Настройки юнитов systemd хранит в памяти. Поэтому, если изменить файл юнита, systemd не заметит изменений, пока его не попросить перечитать конфигурацию командой systemctl daemon-reload. 

Юниты: то, чем управляет systemd

Объекты, которыми управляет systemd, называются юнитами (unit). Тип юнита определяется суффиксом его имени. Основные типы:

  • .service – служба, например, nginx.service. Так оформляют веб-серверы, базы данных и другие приложения, которые работают в фоне.
  • .timer – таймер, который запускает связанный с ним юнит по расписанию или через заданный интервал. Это альтернатива cron: задание описывается юнитом, а результат его выполнения виден в журнале. Например, в Ubuntu и Debian при установке certbot из репозитория certbot.timer дважды в сутки запускает службу, которая проверяет, не пора ли продлить TLS-сертификаты. Если certbot установлен через snap, таймер называется snap.certbot.renew.timer.
  • .socket – сетевой сокет, Unix-сокет или FIFO. systemd может сам слушать сокет и запускать связанную службу при первом обращении к нему.
  • .target – цель, которая объединяет юниты и задает определенное состояние системы. Например, multi-user.target соответствует многопользовательскому режиму без графической оболочки – обычному режиму работы сервера.
  • .mount – точка монтирования файловой системы.
  • .path – наблюдение за файлом или каталогом: когда выполняется заданное условие, например, файл появился или изменился, systemd запускает связанную службу.

Есть и другие типы – .device, .swap, .automount, .slice, .scope, – но при администрировании VPS с ними приходится работать редко.

Чаще всего администратор работает со службами, поэтому в большинстве примеров ниже используется служба веб-сервера nginx. С юнитами других типов команды те же, только имя нужно указывать с суффиксом, например, systemctl status certbot.timer. Если суффикс не указан, systemctl считает, что речь идет о службе, и добавляет .service сам.

Как запустить и остановить службу

Для управления службами нужны права суперпользователя, поэтому в примерах используется sudo. Смотреть состояние службы можно и без них, но тогда в выводе systemctl status могут не отобразиться строки журнала. Чтобы их увидеть, выполните команду через sudo.

Запустить службу можно командой sudo systemctl start <имя_службы>. Например: 

sudo systemctl start nginx

Для остановки используется sudo systemctl stop <имя_службы>. Например: 

sudo systemctl stop nginx

Команды start и stop меняют только текущее состояние службы. После перезагрузки VPS служба запустится, только если для нее включен автозапуск или она нужна другому юниту. Как включить автозапуск – в разделе «Как включить и отключить автозапуск службы».

Обратите внимание!
В Ubuntu и Debian пакеты со службами обычно сразу включают автозапуск и запускают службу при установке. Поэтому, например, nginx начинает работать сразу после apt install nginx.

Как перезапустить службу

Команда restart останавливает службу и запускает ее заново. Если служба была остановлена, команда просто запустит ее:

sudo systemctl restart nginx

Перезапуск нужен, чтобы применить изменения, которые требуют повторного запуска службы, или восстановить ее работу после сбоя. Во время перезапуска служба недоступна, а активные соединения обрываются.

Reload: перечитать конфигурацию без перезапуска

Многие службы умеют применять новую конфигурацию без остановки. Для этого используйте команду:

sudo systemctl reload nginx

Если в юните задана команда перезагрузки конфигурации (параметр ExecReload=), systemd выполняет ее. Основной процесс службы продолжает работать, и соединения не обрываются. Например, nginx при reload запускает новые рабочие процессы с обновленной конфигурацией, а старые завершают обработку текущих запросов и останавливаются.

Если служба не поддерживает reload, команда завершится ошибкой. Например, так выглядит попытка перезагрузить конфигурацию cron в Ubuntu:

Failed to reload cron.service: Job type reload is not applicable for unit cron.service.

systemctl reload перечитывает только конфигурацию самого приложения, например, файлы в /etc/nginx/ для nginx. Если вы изменили файл юнита службы, systemctl reload эти изменения не применит: выполните sudo systemctl daemon-reload, а затем перезапустите службу. 

Универсальная команда reload-or-restart

Если вы не знаете, поддерживает ли служба reload, используйте systemctl reload-or-restart:

sudo systemctl reload-or-restart nginx

Команда перечитывает конфигурацию, если юнит это поддерживает, а в противном случае перезапускает службу. Если служба остановлена, команда ее запустит.

Как включить и отключить автозапуск службы

Чтобы systemd запускал службу при загрузке VPS, выполните:

sudo systemctl enable nginx

Команда создает символические ссылки, которые описаны в секции [Install] файла юнита, – так служба становится частью загрузки системы.

Отключите автозапуск командой:

sudo systemctl disable nginx

systemctl enable не запускает службу сразу, а systemctl disable не останавливает уже работающую. Чтобы сделать и то и другое одной командой, добавьте флаг --now:

sudo systemctl enable --now nginx
sudo systemctl disable --now nginx

Проверьте, включен ли автозапуск:

systemctl is-enabled nginx

Основные ответы команды:

  • enabled – автозапуск включен;
  • disabled – автозапуск отключен;
  • masked – юнит заблокирован, запустить его нельзя;
  • static – у юнита нет секции [Install], поэтому включить его нельзя; такие юниты запускаются как зависимости других юнитов или по таймеру;
  • enabled-runtime – автозапуск включен до следующей перезагрузки (командой enable --runtime).

Полный список состояний приведен в документации systemctl в описании команды is-enabled.

Как заблокировать и разблокировать службу: mask и unmask

Команда disable отключает только автозапуск: службу по-прежнему можно запустить вручную, и ее может запустить другой юнит как зависимость. Чтобы запретить любой запуск, используйте маскирование:

sudo systemctl mask apache2

systemd создаст в директории /etc/systemd/system/ ссылку apache2.service, указывающую на /dev/null. Пока маска действует, службу нельзя запустить ни вручную, ни через зависимости других юнитов:

Failed to start apache2.service: Unit apache2.service is masked.

Команда mask не останавливает уже работающую службу. Чтобы замаскировать и сразу остановить ее, добавьте --now:

sudo systemctl mask --now apache2

Снимите блокировку командой:

sudo systemctl unmask apache2

systemctl unmask удаляет ссылку на /dev/null и возвращает юнит в состояние, в котором он был до маскирования. Если автозапуск был включен, он сохранится, и служба запустится при следующей загрузке. Проверьте это командой systemctl is-enabled apache2.

Маскирование применяется к службам, установленным из пакетов. Для собственной службы, файл которой вы создали в /etc/systemd/system/, команда mask не сработает: ссылку на /dev/null systemd создает в этом же каталоге, а файл с таким именем там уже есть:

Failed to mask unit: File /etc/systemd/system/myapp.service already exists.

Если собственная служба больше не нужна, можно остановить ее, отключить автозапуск и удалить файл юнита:

sudo systemctl disable --now myapp
sudo rm /etc/systemd/system/myapp.service
sudo systemctl daemon-reload

Блокируйте юниты осторожно: если заблокировать юнит, от которого зависят другие службы или загрузка системы, они перестанут работать.

Как узнать состояние службы

Основная команда для диагностики – status. Она показывает состояние службы, ее процессы и последние записи журнала:

systemctl status nginx

Пример вывода:

● nginx.service - A high performance web server and a reverse proxy server
     Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; preset: enabled)
     Active: active (running) since Fri 2026-09-18 12:22:58 UTC; 8min ago
       Docs: man:nginx(8)
   Main PID: 1534 (nginx)
      Tasks: 2 (limit: 2315)
     Memory: 1.7M (peak: 3.9M)
        CPU: 191ms
     CGroup: /system.slice/nginx.service
             ├─1534 "nginx: master process /usr/sbin/nginx -g daemon on; master_process on;"
             └─1537 "nginx: worker process"

Sep 18 12:22:58 ugwhktphat systemd[1]: Starting nginx.service - A high performance web server and a reverse proxy server...
Sep 18 12:22:58 ugwhktphat systemd[1]: Started nginx.service - A high performance web server and a reverse proxy server.

Что означает каждая строка:

  • значок в начале строки – визуальный индикатор состояния юнита;
  • Loaded – загружен ли юнит, путь к его файлу, состояние автозапуска и preset – настройка автозапуска по умолчанию, которую задает дистрибутив;
  • Active – текущее состояние юнита и время, с которого он в нем находится;
  • Docs – ссылка на документацию из настроек юнита;
  • Main PID – идентификатор главного процесса службы;
  • Tasks – число процессов и потоков службы и в скобках их максимальное количество;
  • Memory – объем памяти, который использует служба, и пиковое потребление;
  • CPU – процессорное время, израсходованное с момента запуска;
  • CGroup – контрольная группа, через которую systemd учитывает процессы службы, и дерево этих процессов;
  • строки внизу – последние записи журнала, связанные с юнитом.

В примере служба nginx загружена и настроена на автозапуск (enabled), а preset: enabled указывает, что автозапуск включен и по умолчанию. Служба работает (active (running)) с 12:22:58 UTC. Главный процесс имеет PID 1534, всего служба использует два процесса. Пиковое потребление памяти составило 3,9 МБ, а процессорное время – 191 мс. Внизу журнала видны сообщения об успешном запуске nginx. 

Что показывает поле Active

Основные варианты:

  • active (running) – служба запущена, ее процесс работает;
  • active (exited) – юнит активен, хотя его процесс уже завершился. Так выглядят службы, которые выполняют разовую задачу при загрузке (Type=oneshot с параметром RemainAfterExit=yes), например, ufw.service;
  • active (waiting) – так выглядит работающий таймер, который ждет следующего срабатывания;
  • inactive (dead) – юнит не запущен;
  • failed – юнит завершился с ошибкой или не смог запуститься. В скобках указывается причина, например, failed (Result: exit-code);
  • activating (auto-restart) – служба упала, и systemd ждет паузу перед повторным запуском.

Короткие проверки

Когда подробный вывод не нужен, используйте команды с кратким ответом:

systemctl is-active nginx
systemctl is-enabled nginx
systemctl is-failed nginx
  • is-active выводит состояние юнита: active, inactive, failed и др.;
  • is-enabled выводит состояние автозапуска: enabled, disabled, masked, static и др.;
  • is-failed выводит то же состояние, что и is-active, – для работающей службы это active. Находится ли юнит в состоянии сбоя, команда сообщает кодом возврата: 0 – юнит в состоянии failed, любое другое значение – нет. Посмотреть код возврата можно командой echo $? сразу после проверки.

Эти команды удобно использовать в скриптах: с флагом --quiet они ничего не выводят и сообщают результат только кодом возврата. Например, так можно запустить nginx, если он не работает:

if ! systemctl is-active --quiet nginx; then
  sudo systemctl start nginx
fi

Как посмотреть список служб

Если на сервере возникла проблема и неизвестно, какой юнит ее вызывает, начните с поиска сбоев:

systemctl --failed

Команда показывает все юниты в состоянии failed – не только службы. Чтобы оставить в списке только службы, добавьте фильтр по типу:

systemctl --failed --type=service

Список служб, загруженных в systemd, выводит команда:

systemctl list-units --type=service

По умолчанию в нем только работающие службы, службы с ожидающими заданиями и сбойные. Чтобы увидеть и остановленные, добавьте --all:

systemctl list-units --type=service --all

Чтобы посмотреть все установленные файлы служб и состояние их автозапуска, используйте:

systemctl list-unit-files --type=service

Команда показывает все файлы служб, которые есть в системе, – в том числе тех, которые ни разу не запускались, – и их состояние: enabled, disabled, static или masked.

Разница между командами: list-units показывает юниты, загруженные в память systemd, и их текущее состояние, а list-unit-files – файлы юнитов на диске и настройку их автозапуска.

Как посмотреть логи службы: journalctl

Сообщения служб собирает системный журнал systemd-journald. Журнал хранится в бинарном формате, поэтому для его просмотра используется утилита journalctl.

Посмотрите журнал конкретной службы с помощью флага -u:

sudo journalctl -u nginx

Записей может быть много. Чтобы сразу перейти к последним, добавьте -e:

sudo journalctl -u nginx -e

Чтобы следить за новыми записями в реальном времени, используйте -f – это аналог tail -f. Для выхода нажмите Ctrl+C:

sudo journalctl -u nginx -f

Вывод можно ограничить по времени. Показать записи за сегодня, начиная с полуночи:

sudo journalctl -u nginx --since today

Показать записи за последний час:

sudo journalctl -u nginx --since "1 hour ago"

Если служба не запустилась, systemd предлагает посмотреть журнал командой вида journalctl -xeu nginx.service. В ней -u выбирает юнит, -e переходит к последним записям, а -x добавляет к сообщениям пояснения из каталога сообщений systemd, если они есть:

sudo journalctl -xeu nginx

Для диагностики удобно сочетать обе утилиты: systemctl status показывает текущее состояние службы и несколько последних строк журнала, а journalctl – всю историю с фильтрами по времени и в реальном времени.

По журналу часто можно определить причину сбоя: ошибку в конфигурации, отсутствующий файл или занятый порт. Но в журнал попадает только то, что служба пишет в стандартный вывод или системный журнал. Многие серверные программы ведут собственные логи. Например, nginx записывает ошибки и запросы в /var/log/nginx/error.log и /var/log/nginx/access.log, поэтому в journalctl -u nginx будут в основном сообщения о запуске и остановке, а также ошибки, возникшие при старте. Подробнее о логах – в статье “Просмотр и настройка логов Linux”. Логи systemctl – один из способов проверить работу служб и найти ошибки.

Как оформить свое приложение как службу

Программы, установленные из пакетов, получают готовые файлы юнитов. Чтобы запускать через systemd собственное приложение, например, на Node.js, Python или Go, для него нужно создать отдельный юнит.

Файлы юнитов хранятся в двух основных каталогах:

  • /usr/lib/systemd/system/ – юниты из пакетов. Не редактируйте их: при обновлении пакета изменения будут перезаписаны;
  • /etc/systemd/system/ – юниты администратора. Если имена совпадают, юнит из этого каталога имеет приоритет над юнитом из пакета.

Подготовка

Для примера создадим службу для приложения на Node.js, которое лежит в каталоге /home/myappuser/myapp.

  1. Создайте отдельного пользователя, от имени которого будет работать приложение. Запускать приложения от root небезопасно:
sudo useradd --system --create-home --shell /usr/sbin/nologin myappuser
  1. Узнайте полный путь к интерпретатору Node.js:
command -v node

Файл юнита

Создайте файл:

sudo nano /etc/systemd/system/myapp.service

Добавьте в него:

[Unit]
Description=My Node.js application
After=network.target

[Service]
User=myappuser
WorkingDirectory=/home/myappuser/myapp
ExecStart=/usr/bin/node /home/myappuser/myapp/index.js
Environment=NODE_ENV=production
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

Файл состоит из трех секций.

  1. [Unit] – общая информация о юните и его зависимостях. Description – описание, которое отображается, например, в выводе systemctl status. After=network.target задает только порядок: если обе цели запускаются вместе, служба стартует после инициализации сети.
  2. [Service] – параметры запуска:
  • User – пользователь, от имени которого работает процесс;
  • WorkingDirectory – рабочий каталог процесса;
  • ExecStart – команда запуска. Systemd не использует переменную PATH вашей сессии: без полного пути он ищет программу только в стандартных каталогах (/usr/local/bin, /usr/bin и др.). Поэтому надежнее всегда указывать абсолютный путь. Относительные пути вроде ./index.js не допускаются;
  • Environment – переменные окружения;
  • Restart=on-failure – systemd перезапустит службу, если процесс завершится с ошибкой;
  • RestartSec=5 – пауза перед перезапуском. По умолчанию она составляет всего 100 мс, и при постоянно падающем приложении systemd быстро исчерпает лимит попыток (см. ошибку Start request repeated too quickly).
  1. [Install] – настройки автозапуска, wantedBy=multi-user.target указывает, к какой цели привязать службу при выполнении systemctl enable.

Запуск

Сообщите systemd о новом файле:

sudo systemctl daemon-reload

Включите автозапуск и сразу запустите службу:

sudo systemctl enable --now myapp

Проверьте, что служба работает:

systemctl status myapp

Теперь приложением можно управлять теми же командами, что и любой другой службой: start, stop, restart, enable, disable. Команда systemctl reload для этого юнита не сработает: в нем не задан параметр ExecReload=.

Частые ошибки

Unit not found

Пример ошибки при запуске: 

Failed to start myapp.service: Unit myapp.service not found.

При systemctl status сообщение выглядит так:

Unit myapp.service could not be found.

systemd не нашел юнит с таким именем. Проверьте название службы и наличие файла:

systemctl list-unit-files | grep -i myapp

Если юнит создан вручную, убедитесь, что файл лежит в /etc/systemd/system/ и имеет суффикс .service, и выполните sudo systemctl daemon-reload.

Правка файла юнита не применилась

systemctl выводит предупреждение:

Warning: The unit file, source configuration file or drop-ins of myapp.service changed on disk. Run 'systemctl daemon-reload' to reload units.

Перечитайте файлы юнитов и перезапустите службу

sudo systemctl daemon-reload
sudo systemctl restart myapp

Neither a valid executable name nor an absolute path

При запуске или перезапуске службы появляется ошибка:

Failed to restart myapp.service: Unit myapp.service has a bad unit file setting.
See system logs and 'systemctl status myapp.service' for details.

В строке Loaded вывода systemctl status указано bad-setting, а в журнале (sudo journalctl -u myapp) – причина:

/etc/systemd/system/myapp.service:8: Neither a valid executable name nor an absolute path: ./myapp
myapp.service: Unit configuration has fatal error, unit will not be started.

В ExecStart указан относительный путь. Укажите абсолютный, например, ExecStart=/home/myappuser/myapp/myapp, проверьте, что у файла есть право на выполнение, и выполните sudo systemctl daemon-reload.

Если служба уже работала до правки, ее процесс продолжит работать со старыми настройками: systemd не остановит его, но и не перезапустит, пока ошибка не исправлена.

Unit is masked

Пример ошибки: 

Failed to start nginx.service: Unit nginx.service is masked.

Служба заблокирована командой systemctl mask. Снимите блокировку и запустите службу:

sudo systemctl unmask nginx
sudo systemctl start nginx

Start request repeated too quickly

В выводе systemctl status указано Active: failed, а в журнале есть строки:

myapp.service: Scheduled restart job, restart counter is at 5.
myapp.service: Start request repeated too quickly.
myapp.service: Failed with result 'exit-code'.

Служба запускалась слишком часто – по умолчанию больше 5 раз за 10 секунд, – и systemd перестал ее запускать. Найдите причину в журнале (sudo journalctl -u myapp -e) и устраните ее. Затем сбросьте счетчик попыток и запустите службу:

sudo systemctl reset-failed myapp
sudo systemctl start myapp

Job type reload is not applicable

Пример ошибки:

Failed to reload myapp.service: Job type reload is not applicable for unit myapp.service.

Служба не поддерживает systemctl reload. Используйте sudo systemctl restart myapp или sudo systemctl reload-or-restart myapp.

Заключение

С помощью systemctl можно запускать, останавливать и перезапускать службы, настраивать их автозапуск и блокировать нежелательные службы, а вместе с journalctl – находить причины сбоев. Для собственного приложения начните с минимального юнита из этой статьи и добавляйте параметры по мере необходимости.

Если возникнут вопросы, напишите нам, пожалуйста, тикет из панели управления аккаунта (раздел “Помощь и поддержка”), а если вы захотите обсудить, что делает команда Systemctl, или просто пообщаться с коллегами по цеху и сотрудниками Beget – ждем вас в нашем сообществе в Telegram.