Заощадьте 15% на всіх хостингових послугах

Перевірте свої навички і отримайте Знижку на будь-який план хостингу

Використовуй код: Skills Почати
Рубрики
Linux Адміністрація Віртуальні сервери

Як використовувати systemd для запуску служби Linux при завантаженні

Забезпечення автоматичного запуску критичних служб при перезавантаженні сервера — одна з найфундаментальніших відповідальностей будь-якого системного адміністратора Linux. Незалежно від того, чи ви запускаєте веб-додаток, механізм бази даних або користувацький демон у середовищі VPS Hosting, несподіване перезавантаження ніколи не повинно означати тривалий простій. За допомогою systemd — сучасної системи ініціалізації, яка живить більшість сучасних дистрибутивів Linux — ви можете точно визначити, як, коли та від кого запускаються ваші служби, все через чистий декларативний файл модуля.

Цей комплексний посібник проведе вас через кожен крок: розуміння того, що таке systemd, створення готового до виробництва файлу модуля служби, перевірка дозволів, тестування вашого виконуваного файлу та управління життєвим циклом служби. Наприкінці ваш користувацький додаток буде автоматично пережити кожне перезавантаження.

Що таке systemd і чому це важливо?

systemd — це система ініціалізації та менеджер сервісів, який замінив старіші альтернативи, такі як SysVinit та Upstart, у більшості основних дистрибутивів Linux, включаючи Ubuntu, Debian, CentOS, Rocky Linux, AlmaLinux та Fedora. Замість послідовного виконання ланцюга shell-скриптів під час завантаження, systemd паралелізує запуск сервісів, розв’язує впорядкування залежностей та керує всім життєвим циклом системних процесів з єдиного, уніфікованого інтерфейсу.

Ключові переваги systemd для серверних середовищ

ФункціяПереваги
Паралельний запуск сервісівШвидше завантаження на серверах з багатьма сервісами
Управління залежностямиСервіси запускаються тільки після того, як їхні передумови готові
Політики автоматичного перезапускуУпалі сервіси відновлюються без ручного втручання
Централізоване логування через journaldВесь вивід сервісу захоплюється в журналі, який можна запитувати
Контроль ресурсів на основі cgroupОбмеження CPU та пам’яті застосовуються для кожного сервісу
Активація сокетів та пристроївСервіси запускаються за запитом, а не безумовно

Для всіх, хто керує додатками на Dedicated Servers або VPS екземплярах, ці можливості безпосередньо перекладаються на вищу безперервність роботи та більш передбачувану поведінку під навантаженням.

Розуміння файлів модулів systemd

Все, що керує systemd, представлено файлом модуля — звичайним текстовим файлом конфігурації, розділеним на розділи. Файл модуля .service повідомляє systemd:

  • Що являє собою служба (метадані, опис, залежності)
  • Як її запустити (шлях до виконуваного файлу, робочий каталог, контекст користувача)
  • Коли її запустити (цільовий завантажувач, впорядкування відносно інших модулів)
  • Що робити, якщо вона не вдасться (політика перезапуску, затримка перезапуску)

Файли модулів служб для системних служб розташовуються в /etc/systemd/system/. Файли, розміщені тут, мають пріоритет над постачальниками модулів у /lib/systemd/system/ і зберігаються під час оновлення пакетів.

Крок за кроком: Створення модуля служби systemd

Наступний посібник використовує вигадану програму під назвою myapp. Замініть кожен екземпляр myapp, myuser та /usr/bin/myapp значеннями, відповідними вашому середовищу.

Крок 1: Підготовка робочої директорії

Перед написанням файлу модуля вирішіть, звідки буде запускатися ваша програма. Виділена робоча директорія організує файли конфігурації, журнали та дані часу виконання та спрощує управління дозволами.

Створіть директорію, якщо вона ще не існує:

sudo mkdir -p /opt/myapp

> Чому /opt/ замість /etc/systemd/?

> Дерево /etc/systemd/ зарезервоване для власної конфігурації systemd. Розміщення даних програми там є нестандартним і може спричинити плутанину. Використовуйте /opt/myapp, /srv/myapp або /var/lib/myapp залежно від категорії Стандарту ієрархії файлової системи, яка найкраще відповідає вашому навантаженню.

Призначте власника користувачу, який буде запускати службу:

sudo useradd --system --no-create-home --shell /usr/sbin/nologin myuser
sudo chown -R myuser:myuser /opt/myapp

Використання виділеного системного облікового запису (без оболонки входу, без домашної директорії) є найкращою практикою безпеки. Це обмежує радіус ураження, якщо програма коли-небудь буде скомпрометована.

Перевірте результат:

ls -ld /opt/myapp
# Expected output: drwxr-xr-x 2 myuser myuser 4096 Jan 1 00:00 /opt/myapp

Крок 2: Створення файлу модуля служби

Відкрийте новий файл модуля у вашому улюбленому редакторі:

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

Вставте наступний вміст, коригуючи значення відповідно до вашої програми:

[Unit]
Description=My Custom Application
Documentation=https://example.com/docs
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
ExecStart=/usr/bin/myapp --config /opt/myapp/myapp.conf
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
RestartSec=5s
User=myuser
Group=myuser
WorkingDirectory=/opt/myapp
StandardOutput=journal
StandardError=journal
SyslogIdentifier=myapp

# Security hardening
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true

[Install]
WantedBy=multi-user.target

Збережіть файл за допомогою Ctrl+O, потім вийдіть за допомогою Ctrl+X.

Крок 3: Розуміння кожної директиви

[Unit] Секція

ДирективаПризначення
DescriptionЗрозуміла людиною назва, показана у виводі systemctl status
DocumentationПосилання на URL або сторінку посібника для служби
AfterЗабезпечує запуск служби *після* того, як наведений модуль активний
WantsМ’яка залежність — systemd *спробує* запустити наведений модуль, але не буде невдалим, якщо він недоступний

> network-online.target проти network.target: Використовуйте network-online.target (у поєднанні з Wants=network-online.target) для служб, які справді потребують повністю налаштованого мережевого інтерфейсу — наприклад, програма, яка підключається до віддаленої бази даних або зовнішнього API під час запуску. network.target гарантує лише те, що підсистема мережі була *запущена*, а не те, що інтерфейси активні та адреси призначені.

[Service] Секція

ДирективаПризначення
Type=simpleПроцес, запущений ExecStart, є основним процесом (за замовчуванням для більшості програм)
ExecStartПовний шлях до двійкового файлу та будь-які аргументи. Завжди використовуйте абсолютні шляхи.
ExecReloadКоманда для перезавантаження конфігурації без повного перезапуску (необов’язково, але рекомендується)
Restart=on-failureПерезапустіть службу лише коли вона завершується з ненульовим кодом або вбивається сигналом. Використовуйте always, якщо ви хочете перезапусків навіть при чистому виході.
RestartSecСекунди очікування перед спробою перезапуску
User / GroupЗапустіть процес як цей користувач/група замість root
WorkingDirectoryВстановіть поточну директорію перед виконанням ExecStart
StandardOutput / StandardErrorМаршрутизуйте stdout/stderr до журналу systemd
SyslogIdentifierТег, використовуваний для фільтрування записів журналу для цієї служби
NoNewPrivilegesЗапобігає отриманню процесом додаткових привілеїв через двійкові файли setuid
ProtectSystem=strictМонтує /usr, /boot та /etc як лише для читання для служби
ProtectHomeРобить /home, /root та /run/user недоступними
PrivateTmpНадає службі власний приватний простір імен /tmp

[Install] Секція

ДирективаПризначення
WantedBy=multi-user.targetУвімкнення служби, коли система досягає стандартного рівня запуску для багатокористувача (без графіки). Це правильна ціль для практично всіх демонів сервера.

Крок 4: Перевірка дозволів файлу та директорії

Перед перезавантаженням systemd переконайтеся, що користувач служби насправді може отримати доступ до всього, що йому потрібно:

# Check working directory ownership and permissions
ls -ld /opt/myapp

# Confirm the executable exists and is executable
ls -l /usr/bin/myapp

# Verify the config file is readable by myuser
sudo -u myuser cat /opt/myapp/myapp.conf

Якщо якась з цих перевірок не вдалася, виправте дозволи перед продовженням:

# Make the binary executable
sudo chmod +x /usr/bin/myapp

# Grant read access to the config file
sudo chmod 640 /opt/myapp/myapp.conf
sudo chown myuser:myuser /opt/myapp/myapp.conf

Крок 5: Ручне тестування виконуваного файлу

Завжди перевіряйте, що ваша програма працює правильно *перед* передачею контролю systemd. Це ізолює помилки програми від проблем конфігурації systemd:

sudo -u myuser /usr/bin/myapp --config /opt/myapp/myapp.conf

Якщо програма запускається без помилок, натисніть Ctrl+C для її зупинення та продовжуйте. Якщо вона не вдалася, усуньте саму програму — перевірте, що всі залежності встановлені, змінні середовища встановлені та необхідні порти доступні.

Крок 6: Перезавантаження systemd та увімкнення служби

Після збереження файлу модуля дайте systemd вказівку повторно прочитати його конфігурацію:

sudo systemctl daemon-reload

Увімкніть службу, щоб вона автоматично запускалася при кожному наступному завантаженні:

sudo systemctl enable myapp.service

Ця команда створює символічне посилання у відповідній директорії .wants, пов’язуючи ваш файл модуля з послідовністю завантаження multi-user.target. Ви повинні побачити вихід, подібний до:

Created symlink /etc/systemd/system/multi-user.target.wants/myapp.service → /etc/systemd/system/myapp.service.

Запустіть службу негайно без перезавантаження:

sudo systemctl start myapp.service

Крок 7: Перевірка запуску служби

Перевірте поточний стан служби:

sudo systemctl status myapp.service

Здорова служба видає вихід, подібний до цього:

● myapp.service - My Custom Application
     Loaded: loaded (/etc/systemd/system/myapp.service; enabled; vendor preset: disabled)
     Active: active (running) since Wed 2025-01-01 12:00:00 UTC; 5s ago
   Main PID: 12345 (myapp)
      Tasks: 4 (limit: 4915)
     Memory: 12.3M
        CPU: 45ms
     CGroup: /system.slice/myapp.service
             └─12345 /usr/bin/myapp --config /opt/myapp/myapp.conf

Ключові поля для перевірки:

  • Loaded — підтверджує, що файл модуля був успішно розібраний, і показує, чи він enabled або disabled для завантаження
  • Active: active (running) — служба наразі запущена
  • Main PID — ідентифікатор процесу вашої програми

Крок 8: Моніторинг журналів за допомогою journalctl

systemd маршрутизує весь вихід служби до журналу, структурованого, придатного для запитів сховища журналів. Використовуйте journalctl для його перевірки:

# View all logs for myapp (most recent last)
journalctl -u myapp.service

# Follow live log output (like tail -f)
journalctl -u myapp.service -f

# Show only logs since the last boot
journalctl -u myapp.service -b

# Show the last 50 lines
journalctl -u myapp.service -n 50

# Show logs since a specific time
journalctl -u myapp.service --since "2025-01-01 12:00:00"

Якщо ваша служба не запускається, журнал майже завжди містить точне повідомлення про помилку, яке пояснює чому. Це перше місце для пошуку перед внесенням будь-яких змін.

Крок 9: Тестування поведінки при завантаженні

Щоб підтвердити, що служба пережить перезавантаження без ручної перевірки послідовності завантаження, ви можете імітувати це:

# Reboot the server (only if safe to do so)
sudo reboot

Після повернення сервера в мережу перевірте стан служби ще раз:

sudo systemctl status myapp.service

Якщо вона показує active (running), ваша служба правильно налаштована для автоматичного запуску.

Управління життєвим циклом сервісу

Коли ваш сервіс запущено, ви регулярно використовуватимете такі команди:

Поширені команди systemctl

# Start the service
sudo systemctl start myapp.service

# Stop the service gracefully
sudo systemctl stop myapp.service

# Restart the service (stop + start)
sudo systemctl restart myapp.service

# Reload configuration without restarting (if ExecReload is defined)
sudo systemctl reload myapp.service

# Enable automatic startup at boot
sudo systemctl enable myapp.service

# Disable automatic startup at boot
sudo systemctl disable myapp.service

# Check whether the service is enabled
sudo systemctl is-enabled myapp.service

# Check whether the service is currently active
sudo systemctl is-active myapp.service

# View the full unit file as systemd interprets it
sudo systemctl cat myapp.service

# Edit the unit file and reload in one step
sudo systemctl edit --full myapp.service

Усунення поширених проблем

Служба не запускається: “No such file or directory”

Зазвичай це означає, що ExecStart вказує на неіснуючий бінарний файл або WorkingDirectory не існує. Перевірте обидві шляхи:

which myapp
ls -l /opt/myapp

Служба запускається, але негайно завершується

Перевірте журнал для власного виводу помилок програми:

journalctl -u myapp.service -n 100 --no-pager

Також перевірте, що Type=simple правильний для вашої програми. Якщо ваш бінарний файл розгалужується на фоні, використовуйте Type=forking замість цього.

“Permission denied” помилки

Користувач служби не має доступу до необхідного файлу або каталогу. Використовуйте ls -l для аудиту дозволів і sudo -u myuser для інтерактивної перевірки доступу.

Порт уже використовується

Інший процес прив’язаний до порту, який потребує ваша програма. Визначте його за допомогою:

sudo ss -tlnp | grep :<port>

Служба перезапускається в циклі

Якщо Restart=on-failure викликає цикли швидкого перезапуску, systemd врешті-решт обмежить перезапуски. Перевірте StartLimitIntervalSec і StartLimitBurst у розділі [Unit] для налаштування цієї поведінки, і завжди дослідіть основну причину в журналі.

Advanced systemd Patterns for Production Servers

Змінні середовища та файли середовища

Ніколи не жорстко кодуйте секрети в файлах модулів. Замість цього використовуйте файл середовища:

[Service]
EnvironmentFile=/etc/myapp/myapp.env
ExecStart=/usr/bin/myapp

Створіть /etc/myapp/myapp.env з chmod 600 та chown root:myuser для обмеження доступу:

DATABASE_URL=postgresql://user:password@localhost/mydb
API_KEY=supersecretkey

Залежності служб та впорядкування

Якщо ваша програма залежить від служби бази даних (наприклад, PostgreSQL або MySQL), явно оголосіть цю залежність:

[Unit]
After=network-online.target postgresql.service
Requires=postgresql.service

Requires є жорсткою залежністю — якщо PostgreSQL не запуститься, systemd також не спробує запустити вашу службу.

Інтеграція Watchdog

Для критично важливих служб увімкніть вбудований watchdog systemd для виявлення зависаних процесів:

[Service]
WatchdogSec=30s
Restart=on-watchdog

Ваша програма повинна періодично викликати sd_notify(0, "WATCHDOG=1") для скидання таймера watchdog. Якщо їй не вдасться це зробити протягом WatchdogSec, systemd вбиває та перезапускає службу.

Вибір правильного середовища хостингу

Шаблони конфігурації systemd, описані в цьому посібнику, застосовуються однаково для всіх типів серверів Linux, але ваш вибір інфраструктури хостингу впливає на те, скільки контролю ви маєте над системою ініціалізації та управлінням сервісами.

  • VPS Hosting — Повний root доступ, повний контроль systemd, ідеально для користувацьких розгортань додатків. VPS плани AlexHost працюють на KVM віртуалізації, надаючи вам справжнє ізольоване середовище ядра.
  • Dedicated Servers — Максимальна продуктивність та ізоляція для ресурсомістких сервісів. Повний доступ до обладнання без шумних сусідів.
  • VPS з cPanel — Поєднує root-рівневий доступ systemd з графічною панеллю керування для команд, які керують як системними сервісами, так і веб-хостингом з одного інтерфейсу.
  • Shared Web Hosting — Підходить для стандартних веб-додатків, які не потребують користувацьких системних сервісів. Без root доступу, але нульові витрати на управління сервером.

Якщо ви розгортаєте користувацький демон, мікросервіс або будь-який додаток, який повинен автоматично пережити перезавантаження, VPS або виділений сервер з повним root доступом — це правильний вибір.

Швидкий довідник: Повний контрольний список systemd Service

Перед тим як вважати вашу службу готовою до виробництва, перевірте кожен пункт цього контрольного списку:

  • [ ] Файл Unit збережено в /etc/systemd/system/myapp.service
  • [ ] ExecStart використовує абсолютний шлях до дійсного, виконуваного бінарного файлу
  • [ ] WorkingDirectory існує та належить користувачу служби
  • [ ] Служба запускається як виділений непривілейований системний обліковий запис
  • [ ] sudo systemctl daemon-reload виконано після будь-якої зміни файлу Unit
  • [ ] sudo systemctl enable myapp.service підтверджує, що символічне посилання було створено
  • [ ] sudo systemctl status myapp.service показує active (running)
  • [ ] journalctl -u myapp.service не показує помилок
  • [ ] Сервер перезавантажено та служба підтверджена як запущена після завантаження
  • [ ] Застосовано директиви посилення безпеки (NoNewPrivileges, ProtectSystem, PrivateTmp)

Висновок

systemd — це визначальний рівень управління сервісами для сучасних серверів Linux. Створивши добре структурований файл модуля .service, ви отримаєте автоматичний запуск при завантаженні, розумні політики перезавантаження, централізоване логування та детальні елементи управління безпекою — все це без написання жодного рядка shell-скрипту.

Процес простий: підготуйте спеціальний робочий каталог і системного користувача, напишіть файл модуля з правильними розділами [Unit], [Service] та [Install], перезавантажте демон systemd, увімкніть і запустіть сервіс, потім перевірте за допомогою systemctl status та journalctl. Застосуйте директиви посилення безпеки, обговорені вище, і ваш сервіс буде як стійким, так і належним чином ізольованим від решти системи.

Незалежно від того, розгортаєте ви Node.js API, Python worker, Go binary чи будь-яку іншу користувацьку програму на плані AlexHost VPS Hosting або Dedicated Servers, цей робочий процес systemd гарантує, що ваш сервіс завжди працює, коли він потрібен вашим користувачам — навіть після несподіваного перезавантаження.