Запустить программу в фоне, обеспечить ее автоматический запуск после перезагрузки сервера, разобраться, почему она перестала отвечать, – все эти задачи на Линукс-сервере решает 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 служба запустится, только если для нее включен автозапуск или она нужна другому юниту. Как включить автозапуск – в разделе «Как включить и отключить автозапуск службы».
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 nginxsystemctl 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 apache2systemd создаст в директории /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 apache2systemctl 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 nginxis-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.
- Создайте отдельного пользователя, от имени которого будет работать приложение. Запускать приложения от
rootнебезопасно:
sudo useradd --system --create-home --shell /usr/sbin/nologin myappuser- Узнайте полный путь к интерпретатору 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Файл состоит из трех секций.
[Unit]– общая информация о юните и его зависимостях.Description– описание, которое отображается, например, в выводеsystemctl status.After=network.targetзадает только порядок: если обе цели запускаются вместе, служба стартует после инициализации сети.[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).
[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 myappNeither 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 nginxStart 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 myappJob 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.