Як використовувати 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.serviceRequires є жорсткою залежністю — якщо 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 гарантує, що ваш сервіс завжди працює, коли він потрібен вашим користувачам — навіть після несподіваного перезавантаження.
на всіх хостингових послугах