Что такое systemd и что он запускает на вашем VPS
systemd запускает службы на VPS с Ubuntu или Debian и следит за ними. Разбираем юниты, цели, journald и таймеры, разницу между systemd и systemctl и то, что сотрёт обновление пакета.
Что такое systemd, если коротко
systemd является системой инициализации и менеджером служб: на VPS с Ubuntu или Debian он работает как самый первый процесс с номером PID 1 (PID означает идентификатор процесса). Он запускает все остальные программы на сервере, следит за ними и собирает их логи.
Ядро Linux после загрузки само запускает только одну программу. Всё, что работает на сервере потом, запустила она или её потомки. На Ubuntu 24.04 и Debian 12 эта программа и есть systemd. Поэтому, когда SSH или nginx не поднялись после перезагрузки, вопрос всегда к нему: что он пытался запустить и почему остановился.
Проверить, кто у вас PID 1, можно одной командой:
ps -p 1 -o comm=Команда печатает имя процесса с номером 1. На современных Ubuntu и Debian это systemd. В Docker-контейнере там будет ваше приложение, и об этом случае ниже.
Дальше в статье только то, с чем реально сталкивается арендатор VPS: юниты и их файлы, цели, журнал, таймеры и дополнительные компоненты, которые ваш дистрибутив включает сам. Все команды в блоках кода только читают состояние системы. Их можно спокойно запускать на рабочем сервере.
Почему systemd заменил SysV init
До systemd службы на Debian и Ubuntu запускали shell-скрипты из /etc/init.d в стиле SysV init, а Ubuntu несколько лет использовала собственный Upstart. Скрипты мало знали о зависимостях друг от друга, и после запуска никто не следил за процессом. Упавший демон так и оставался упавшим, пока его не замечал человек. systemd описывает службы декларативно, запускает независимые службы параллельно и держит каждый процесс под наблюдением. Debian перешёл на него в версии 8 в 2015 году, Ubuntu в версии 15.04 того же года. Споры вокруг этого перехода и его причины подробно разобраны в истории systemd и войны за систему инициализации, здесь повторять их не будем.
systemd и systemctl: в чём разница
Самый частый вопрос новичка звучит так: «systemctl и systemd одно и то же?» Нет. systemd работает в фоне как PID 1 и ничего не печатает в ваш терминал. systemctl является клиентом. Это небольшая программа, которая передаёт systemd вашу команду и показывает его ответ. journalctl тоже клиент, только для журнала.
Когда вы пишете sudo systemctl restart nginx, nginx перезапускает не systemctl. Его перезапускает systemd по просьбе systemctl. Это различие объясняет одну частую ошибку. В Docker-контейнере PID 1 обычно занимает само приложение, поэтому systemctl там отказывается работать и сообщает, что система загружена не через systemd. Клиенту просто не с кем разговаривать.
Название systemd относится и к целому проекту. В него входит десяток отдельных программ, и у них есть простое правило имён:
- имена на
dпринадлежат демонам, которые работают в фоне:systemd-journald,systemd-logind,systemd-resolved,systemd-timesyncd; - имена на
ctlпринадлежат клиентам, которые вы набираете в терминале:systemctl,journalctl,resolvectl,timedatectl,hostnamectl,loginctl; - каждый клиент управляет своим демоном, например
resolvectlспрашиваетsystemd-resolved; - сам
systemdбез суффикса означает менеджер служб, то есть PID 1.
Юнит: то, чем управляет systemd
Юнит (unit) является единицей, которой управляет systemd. Это служба, таймер, точка монтирования или группа других юнитов. Каждый юнит описан текстовым файлом в формате INI. Имя файла задаёт и имя юнита, и его тип: nginx.service, apt-daily.timer, ssh.socket.
Вот как выглядит файл простой службы. Это пример для вашего собственного приложения, а не файл из какого-то пакета:
[Unit]
Description=My web app
After=network-online.target
Wants=network-online.target
[Service]
User=app
ExecStart=/opt/myapp/bin/server --port 8080
Restart=on-failure
[Install]
WantedBy=multi-user.targetСекция [Unit] описывает связи с другими юнитами. After= задаёт порядок запуска, а Wants= задаёт зависимость. Это разные вещи: After= без Wants= ничего не запускает, а только ждёт, если нужный юнит и так запускается. Секция [Service] говорит, какую команду выполнить, от какого пользователя и что делать при падении. Секция [Install] читается только командой systemctl enable, и об этом ниже.
Строка Type= здесь не указана, поэтому systemd считает службу простой: процесс из ExecStart= и есть служба. Демоны, которые уходят в фон сами, требуют другого типа. С неправильным типом systemd либо останавливает исправную службу, либо ждёт сигнала о запуске до таймаута и считает запуск неудачным. Все варианты с примерами есть в разборе типов служб systemd: simple, forking, notify и oneshot.
Какие типы юнитов встретятся на VPS
.serviceописывает процесс или набор процессов: nginx, sshd, PostgreSQL, ваше приложение..timerзапускает другой юнит по расписанию или через интервал. Это замена cron..socketописывает сокет, который systemd слушает сам и передаёт службе при первом подключении. На Ubuntu 24.04 так по умолчанию запускается SSH: порт держитssh.socket, аsshdстартует при первом соединении..targetобъединяет другие юниты в группу и служит точкой синхронизации при загрузке..mountописывает точку монтирования. systemd сам превращает строки из/etc/fstabв такие юниты при загрузке, поэтому ошибка вfstabвыглядит как упавший юнит..sliceи.scopeописывают группы процессов для учёта и ограничения ресурсов.
Две команды показывают, что есть на вашем сервере:
systemctl list-units --type=service
systemctl list-unit-files --type=serviceПервая показывает юниты, которые systemd сейчас держит в памяти, и их состояние. Вторая показывает все установленные файлы служб и то, включены ли они для автозапуска. Служба может быть установлена, но не загружена, и тогда её видно только во втором списке.
Где лежат юнит-файлы и что перезапишет обновление пакета
systemd ищет юнит-файлы в нескольких каталогах, и расположение файла решает, кто его владелец. Это важно, потому что от этого зависит, переживёт ли ваша правка следующий apt upgrade.
/usr/lib/systemd/system/принадлежит пакетам. Сюдаaptкладёт файлы служб и здесь же заменяет их при каждом обновлении пакета. На Ubuntu 24.04 и Debian 12 путь/lib/systemd/system/ведёт в тот же каталог, потому что/libтам является ссылкой на/usr/lib./etc/systemd/system/принадлежит администратору, то есть вам. Пакеты сюда не пишут, и у этого каталога самый высокий приоритет./run/systemd/system/содержит юниты, созданные во время работы. Он живёт в памяти и очищается при перезагрузке.
Если файл с одним и тем же именем есть и в /etc, и в /usr/lib, systemd полностью игнорирует второй. Отсюда частая ловушка. Администратор копирует nginx.service целиком в /etc/systemd/system/ и меняет одну строку. Правка работает. Но теперь сервер навсегда использует старую копию, и все будущие исправления этого файла от разработчиков пакета до него не доходят.
Правильный путь называется drop-in, то есть файл-дополнение. Он лежит в каталоге /etc/systemd/system/nginx.service.d/ и содержит только те строки, которые вы меняете. systemd читает файл пакета, а потом накладывает поверх него ваши строки. Пакет обновляет свой файл, а ваша правка остаётся. Пример такого файла:
[Service]
Restart=always
LimitNOFILE=65536Команда sudo systemctl edit nginx создаёт такой файл в нужном месте и после сохранения сама перечитывает конфигурацию. Одна тонкость: строка ExecStart= в drop-in не заменяет старое значение, а добавляется к нему. Чтобы заменить команду запуска, сначала напишите пустую строку ExecStart=, а под ней новую.
Две команды только для чтения показывают, что действует на самом деле:
systemctl cat nginx
systemd-delta --type=extended,overriddensystemctl cat печатает основной файл юнита с его путём, а под ним все drop-in файлы в порядке применения. systemd-delta перечисляет все юниты в системе, которые вы переопределили или дополнили. Через полгода после настройки сервера именно эта команда напомнит, что вы меняли.
Если вы правите файл в /etc/systemd/system/ вручную, а не через systemctl edit, выполните sudo systemctl daemon-reload. systemd держит разобранные юниты в памяти. Пока вы не попросите перечитать файлы, он работает со старой версией, а systemctl status предупреждает, что файл на диске изменился.
Цели вместо уровней запуска
Цель (target) является юнитом, который ничего не запускает сам, а только объединяет другие юниты. Сервер загружается в multi-user.target: все службы и сеть, но без графического входа. Настольные системы загружаются в graphical.target, которая включает multi-user.target и добавляет экран входа.
systemctl get-default
systemctl list-dependencies multi-user.targetПервая команда показывает цель загрузки по умолчанию. Вторая показывает дерево юнитов, которые эта цель тянет за собой. Цели заменили старые уровни запуска SysV, и соответствие между ними описано в статье о целях systemd и уровнях запуска.
Одна цель часто сбивает с толку. network.target означает только то, что сетевая подсистема запущена. Адрес к этому моменту может ещё не быть получен. Если служба должна сразу подключиться к удалённой базе, ей нужна network-online.target, как в примере выше.
Команды enable и start делают разные вещи
systemctl start запускает службу сейчас и ничего не говорит о следующей загрузке. systemctl enable ничего не запускает сейчас. Она читает секцию [Install] и создаёт символическую ссылку, например в /etc/systemd/system/multi-user.target.wants/. При загрузке systemd видит эту ссылку и запускает службу вместе с целью. sudo systemctl enable --now myapp делает оба действия сразу.
Отсюда классическая ситуация: служба работала, сервер перезагрузили, служба не поднялась. Её запустили через start, но не включили через enable. Проверить оба состояния можно так:
systemctl is-enabled nginx
systemctl is-active nginxЭто же объясняет, почему контейнеры не стартуют после перезагрузки, если сам docker.service не включён. Как это настроить для Compose, описано в статье про автозапуск Docker Compose при загрузке сервера.
Что systemd делает после запуска службы
Старый скрипт init запускал демон и забывал о нём. systemd помещает каждую службу в отдельную cgroup (control group, группа управления ядра Linux). Ядро записывает в эту группу каждый процесс, который служба порождает, даже если он ушёл в фон. Поэтому systemd всегда знает все процессы службы, а systemctl stop останавливает их все, а не только главный.
Эта же группа даёт ещё две возможности. Первая: перезапуск при падении через Restart=. Вторая: учёт и ограничение ресурсов. systemd-cgls показывает дерево групп и процессов в них, а systemd-cgtop показывает, какая служба сейчас расходует больше всего процессора и памяти. Как ограничить службу по памяти и процессору, описано в статье про ограничение памяти и CPU процесса через systemd. Отдельно systemd умеет изолировать службу от остальной системы, и это разобрано в материале о песочнице systemd: ProtectSystem и PrivateTmp.
Чтобы увидеть, в каком состоянии служба прямо сейчас, есть главная команда:
systemctl status sshОна показывает, загружен ли юнит и из какого файла, включён ли он, активен ли он сейчас, номер главного процесса, группу процессов и последние строки журнала этой службы. На Ubuntu и Debian служба SSH называется ssh, а не sshd, как в Rocky Linux или Fedora.
journald: где systemd хранит логи
systemd-journald собирает в один журнал вывод всех служб и сообщения ядра. Сюда же попадают сообщения, отправленные через syslog. Каждая запись помечена юнитом, который её создал. Поэтому лог одной службы можно получить без поиска по файлам:
journalctl -u ssh
journalctl -u nginx --since "1 hour ago"
journalctl -b -p err
journalctl -f -u nginxПервая команда показывает все записи службы SSH. Вторая ограничивает вывод последним часом. Третья показывает только ошибки с момента текущей загрузки. Четвёртая выводит новые записи по мере появления, как tail -f.
Сохранится ли журнал после перезагрузки, зависит от одного каталога. По умолчанию journald пишет журнал на диск, только если существует /var/log/journal. Если каталога нет, журнал живёт в /run и пропадает при перезагрузке. Тогда journalctl -b -1 (журнал предыдущей загрузки) не покажет предыдущую загрузку как раз тогда, когда она нужнее всего: после неожиданного сбоя. Проверьте заранее:
ls -d /var/log/journal
journalctl --disk-usageНа части систем рядом работает классический rsyslog и пишет текстовые файлы вроде /var/log/syslog. На других этого файла нет, и journald является единственным источником логов. Ни то, ни другое не ошибка.
Таймеры: замена cron от systemd
Таймер является юнитом .timer, который запускает другой юнит по расписанию. Ваш дистрибутив уже использует их сам: на Ubuntu и Debian таймеры запускают, например, фоновое обновление списков пакетов apt и ротацию логов. Посмотреть все таймеры и время их следующего запуска можно так:
systemctl list-timers --allПо сравнению с cron у таймера есть практические плюсы. Вывод каждого запуска попадает в журнал под именем юнита, поэтому journalctl -u показывает историю запусков. Параметр Persistent=true выполняет пропущенный запуск, если сервер был выключен в нужный момент. Задание получает те же ограничения ресурсов и ту же изоляцию, что и обычная служба. Наконец, задание можно запустить вручную для проверки, не дожидаясь расписания. cron при этом никуда не делся и работает. Как написать свою пару из службы и таймера, показано в руководстве по службам и таймерам systemd на VPS.
Какие компоненты systemd включены на Ubuntu и Debian
Пакет systemd приносит больше, чем менеджер служб. Часть компонентов работает везде, часть включает только Ubuntu, часть ставится отдельным пакетом. Ниже состояние для свежих установок, сверенное с документацией Ubuntu и примечаниями к выпускам Debian по состоянию на октябрь 2026 года.
systemd-journaldиsystemd-logindработают на обоих дистрибутивах всегда. logind ведёт учёт сеансов входа, в том числе по SSH. На Ubuntu и Debian он по умолчанию не завершает процессы пользователя при выходе, поэтомуtmuxиscreenпереживают разрыв SSH. Подробнее в статье о том, как оставить команду работать после отключения SSH.systemd-resolvedявляется локальным DNS-резолвером (DNS означает систему доменных имён). На Ubuntu он включён, и/etc/resolv.confуказывает на его локальный адрес. Начиная с Debian 12 его вынесли в отдельный пакетsystemd-resolved, и по умолчанию он не установлен.systemd-networkdнастраивает сетевые интерфейсы. Ubuntu Server описывает сеть в Netplan, а Netplan передаёт настройки в networkd. Debian, установленный штатным установщиком, настраивает сеть через ifupdown и файл/etc/network/interfaces. Образы VPS у разных провайдеров здесь отличаются, поэтому проверьте свой сервер.systemd-timesyncdсинхронизирует часы по NTP (Network Time Protocol, протокол сетевого времени). На Ubuntu 24.04 он используется по умолчанию. Начиная с Ubuntu 25.10, новые установки используют chrony вместо него, а системы, обновлённые со старых версий, могут остаться на timesyncd. В Debian timesyncd является отдельным пакетом.
Не полагайтесь на этот список, проверьте свой сервер:
systemctl is-active systemd-resolved systemd-networkd systemd-timesyncd chrony
timedatectl status
resolvectl statusПервая команда печатает состояние каждого юнита по строке. timedatectl status показывает, синхронизируются ли часы. resolvectl status работает только там, где запущен systemd-resolved. Если на Debian резолвер не установлен, команда не сработает, а DNS настраивается обычным /etc/resolv.conf.
Куда дальше
Теперь у вас есть карта. systemd запускает службы и следит за ними. systemctl и journalctl служат способами с ним говорить. Файлы в /etc/systemd/system/ принадлежат вам. Следующие шаги зависят от задачи.
- Если вы пишете свой юнит, начните с разбора типов служб systemd, потому что строка
Type=определяет, когда systemd считает службу запущенной. - Если вам нужно задание по расписанию, переходите к службам и таймерам systemd на VPS.
- Если служба не стартует, откройте разбор причин, по которым юнит systemd не запускается, и кодов выхода. Начните с
systemctl statusиjournalctl -u имя -b, а статья объяснит, что значат коды. - Если вам интересно, как сервер работает без systemd, загляните в обзор альтернатив systemd для серверов.
FAQ
systemd и systemctl одно и то же?
Нет. systemd является системой инициализации и менеджером служб, он работает в фоне как процесс с PID 1. systemctl является клиентом командной строки, который передаёт systemd команды вроде start или enable и показывает ответ. Службу запускает и останавливает сам systemd. Поэтому в контейнере, где PID 1 не systemd, команда systemctl не работает.
Где лежат файлы служб systemd и какой из них главный?
Файлы из пакетов лежат в /usr/lib/systemd/system/ и заменяются при каждом обновлении пакета. Ваши файлы и правки лежат в /etc/systemd/system/. Пакеты туда не пишут, и у этого каталога приоритет выше. Чтобы изменить службу из пакета, создайте drop-in через sudo systemctl edit имя, а не копируйте весь файл. systemctl cat имя покажет, какие файлы действуют на самом деле.
Почему служба не запустилась после перезагрузки, хотя работала?
Скорее всего, её запустили командой systemctl start, но не включили командой systemctl enable. start действует только до перезагрузки, а enable создаёт ссылку, по которой systemd запускает службу при загрузке. Проверьте systemctl is-enabled имя. Если служба включена, но не поднялась, причину покажут systemctl status имя и journalctl -u имя -b.
Почему journalctl не показывает логи до перезагрузки?
journald по умолчанию сохраняет журнал на диск, только если существует каталог /var/log/journal. Без него журнал хранится в /run, то есть в памяти, и пропадает при каждой перезагрузке. Проверьте каталог командой ls -d /var/log/journal. Журнал предыдущей загрузки показывает journalctl -b -1.
Какие части systemd работают на Ubuntu, а какие на Debian?
journald и logind работают на обоих дистрибутивах. Ubuntu Server дополнительно включает systemd-resolved для DNS и systemd-networkd через Netplan. На Ubuntu 24.04 время синхронизирует systemd-timesyncd, а новые установки начиная с Ubuntu 25.10 используют chrony. Начиная с Debian 12, systemd-resolved является отдельным пакетом и по умолчанию не установлен, а сеть при штатной установке настраивает ifupdown. Команда systemctl is-active с именами юнитов покажет, что включено на вашем сервере.