Systemd сервіси

Systemd — це система ініціалізації та керування службами в сучасних Linux дистрибутивах. Вона запускає сервіси, слідкує за ними, і перезапускає якщо впали.

Основні команди

Управління сервісами

# Статус сервісу
sudo systemctl status nginx

# Запустити сервіс
sudo systemctl start nginx

# Зупинити сервіс
sudo systemctl stop nginx

# Перезапустити (stop + start)
sudo systemctl restart nginx

# Перезавантажити конфіг (без перезапуску)
sudo systemctl reload nginx

Автозапуск

# Увімкнути автозапуск при старті системи
sudo systemctl enable nginx

# Вимкнути автозапуск
sudo systemctl disable nginx

# Увімкнути і запустити одразу
sudo systemctl enable --now nginx

Перегляд сервісів

# Всі сервіси
systemctl list-units --type=service

# Тільки активні
systemctl list-units --type=service --state=running

# Тільки failed
systemctl list-units --type=service --state=failed

# Всі unit файли
systemctl list-unit-files --type=service

Статус сервісу

$ sudo systemctl status nginx

● nginx.service - A high performance web server
     Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
     Active: active (running) since Fri 2026-01-17 10:00:00 UTC; 2h ago
       Docs: man:nginx(8)
    Process: 1234 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; (code=exited, status=0/SUCCESS)
    Process: 1235 ExecStart=/usr/sbin/nginx -g daemon on; (code=exited, status=0/SUCCESS)
   Main PID: 1236 (nginx)
      Tasks: 2 (limit: 1137)
     Memory: 4.5M
        CPU: 25ms
     CGroup: /system.slice/nginx.service
             ├─1236 "nginx: master process /usr/sbin/nginx"
             └─1237 "nginx: worker process"

Розшифровка

┌────────────────────────────────────────────────────────────────┐
│                     СТАТУСИ СЕРВІСУ                            │
├────────────────────────────────────────────────────────────────┤
│                                                                │
│  Active:                                                       │
│  ├── active (running)  — працює                               │
│  ├── active (exited)   — виконався і завершився               │
│  ├── inactive (dead)   — не запущений                         │
│  └── failed            — впав з помилкою                      │
│                                                                │
│  Loaded:                                                       │
│  ├── enabled   — автозапуск увімкнено                         │
│  └── disabled  — автозапуск вимкнено                          │
│                                                                │
└────────────────────────────────────────────────────────────────┘

Логи (journalctl)

# Логи конкретного сервісу
sudo journalctl -u nginx

# Останні 100 рядків
sudo journalctl -u nginx -n 100

# В реальному часі (як tail -f)
sudo journalctl -u nginx -f

# З певного часу
sudo journalctl -u nginx --since "2026-01-17 10:00:00"
sudo journalctl -u nginx --since "1 hour ago"
sudo journalctl -u nginx --since today

# Тільки помилки
sudo journalctl -u nginx -p err

# Все в системі
sudo journalctl

# Логи завантаження
sudo journalctl -b

Рівні пріоритету (-p)

Рівень Опис
emerg Система непрацездатна
alert Потрібна негайна дія
crit Критична помилка
err Помилка
warning Попередження
notice Важливе повідомлення
info Інформація
debug Дебаг
# Помилки та критичніше
sudo journalctl -u nginx -p warning

Типи юнітів

┌────────────────────────────────────────────────────────────────┐
│                     ТИПИ ЮНІТІВ                                │
├────────────────────────────────────────────────────────────────┤
│                                                                │
│  .service  — сервіси (nginx, postgresql)                      │
│  .timer    — таймери (заміна cron)                            │
│  .socket   — сокети (активація по з'єднанню)                  │
│  .target   — групи юнітів (multi-user.target)                 │
│  .mount    — точки монтування                                  │
│  .path     — моніторинг файлів/директорій                     │
│                                                                │
└────────────────────────────────────────────────────────────────┘

Створення свого сервісу

Приклад: Python скрипт як сервіс

Маємо скрипт /opt/myapp/app.py:

#!/usr/bin/env python3
import time

while True:
    print(f"Working... {time.strftime('%H:%M:%S')}")
    time.sleep(60)

Unit файл

Створіть /etc/systemd/system/myapp.service:

[Unit]
Description=My Python Application
After=network.target

[Service]
Type=simple
User=myapp
Group=myapp
WorkingDirectory=/opt/myapp
ExecStart=/usr/bin/python3 /opt/myapp/app.py
Restart=always
RestartSec=5

# Логування
StandardOutput=journal
StandardError=journal

# Безпека
NoNewPrivileges=yes
ProtectSystem=strict
ProtectHome=yes
ReadWritePaths=/opt/myapp/data

[Install]
WantedBy=multi-user.target

Активація

# Перезавантажити конфігурацію systemd
sudo systemctl daemon-reload

# Увімкнути та запустити
sudo systemctl enable --now myapp

# Перевірити статус
sudo systemctl status myapp

# Логи
sudo journalctl -u myapp -f

Структура unit файлу

[Unit] — загальна інформація

[Unit]
# Опис сервісу
Description=My Application Server

# Документація
Documentation=https://example.com/docs

# Залежності — запустити ПІСЛЯ цих юнітів
After=network.target postgresql.service

# Вимагати ці юніти (якщо вони падають — падаємо теж)
Requires=postgresql.service

# Хотіти ці юніти (м'яка залежність)
Wants=redis.service

[Service] — параметри сервісу

[Service]
# Тип сервісу
Type=simple          # Процес залишається на передньому плані
# Type=forking       # Створює дочірній процес і виходить
# Type=oneshot       # Виконується один раз
# Type=notify        # Як simple, але шле сигнал ready

# Команди
ExecStartPre=/usr/bin/prepare.sh   # До запуску
ExecStart=/usr/bin/myapp           # Основна команда
ExecStartPost=/usr/bin/notify.sh   # Після запуску
ExecStop=/usr/bin/myapp stop       # Зупинка
ExecReload=/bin/kill -HUP $MAINPID # Перезавантаження конфігу

# Користувач/група
User=myapp
Group=myapp

# Робоча директорія
WorkingDirectory=/opt/myapp

# Змінні середовища
Environment="NODE_ENV=production"
Environment="PORT=3000"
# Або з файлу
EnvironmentFile=/etc/myapp/env

# Перезапуск
Restart=always       # Завжди перезапускати
# Restart=on-failure # Тільки при помилці
# Restart=no         # Ніколи
RestartSec=5         # Чекати 5 секунд між перезапусками

# Таймаути
TimeoutStartSec=30
TimeoutStopSec=30

[Install] — встановлення

[Install]
# До якого target приєднатись при enable
WantedBy=multi-user.target

# Альтернативні імена
Alias=myapp.service

Практичні приклади

Node.js застосунок

[Unit]
Description=Node.js Application
After=network.target

[Service]
Type=simple
User=node
WorkingDirectory=/opt/nodeapp
ExecStart=/usr/bin/node /opt/nodeapp/server.js
Restart=always
RestartSec=10
Environment="NODE_ENV=production"
Environment="PORT=3000"

# Ліміти
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target

Gunicorn (Python WSGI)

[Unit]
Description=Gunicorn WSGI Server
After=network.target

[Service]
Type=notify
User=www-data
Group=www-data
WorkingDirectory=/opt/mydjango
ExecStart=/opt/mydjango/venv/bin/gunicorn \
    --workers 4 \
    --bind unix:/run/gunicorn.sock \
    myproject.wsgi:application
ExecReload=/bin/kill -s HUP $MAINPID
Restart=on-failure
KillMode=mixed
TimeoutStopSec=5

[Install]
WantedBy=multi-user.target

Docker Compose як сервіс

[Unit]
Description=Docker Compose Application
Requires=docker.service
After=docker.service

[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/opt/mystack
ExecStart=/usr/bin/docker compose up -d
ExecStop=/usr/bin/docker compose down
TimeoutStartSec=0

[Install]
WantedBy=multi-user.target

Таймери (заміна cron)

Створення таймера

Створіть /etc/systemd/system/backup.service:

[Unit]
Description=Backup Script

[Service]
Type=oneshot
ExecStart=/opt/scripts/backup.sh

Створіть /etc/systemd/system/backup.timer:

[Unit]
Description=Run backup daily

[Timer]
# Щодня о 3:00
OnCalendar=*-*-* 03:00:00
# Або
# OnCalendar=daily

# Запустити якщо пропустили (сервер був вимкнений)
Persistent=true

[Install]
WantedBy=timers.target

Активація таймера

sudo systemctl enable --now backup.timer

# Перевірити таймери
systemctl list-timers

# Статус таймера
systemctl status backup.timer

# Запустити вручну
sudo systemctl start backup.service

Формат OnCalendar

OnCalendar=minutely          # Щохвилини
OnCalendar=hourly            # Щогодини
OnCalendar=daily             # Щодня о 00:00
OnCalendar=weekly            # Щотижня
OnCalendar=monthly           # Щомісяця
OnCalendar=*-*-* 03:00:00    # Щодня о 3:00
OnCalendar=Mon *-*-* 10:00   # Щопонеділка о 10:00
OnCalendar=*-*-01 00:00:00   # Першого числа кожного місяця

Troubleshooting

Сервіс не запускається

# 1. Детальний статус
sudo systemctl status myapp

# 2. Повні логи
sudo journalctl -u myapp --no-pager

# 3. Перевірити синтаксис unit файлу
sudo systemd-analyze verify /etc/systemd/system/myapp.service

# 4. Перевірити права на файли
ls -la /opt/myapp/

Сервіс падає в циклі

# Логи падінь
sudo journalctl -u myapp | grep -E "Started|Failed|Stopped"

# Зупинити перезапуск
sudo systemctl stop myapp

Зміни в unit файлі не застосовуються

# ЗАВЖДИ після редагування unit файлу:
sudo systemctl daemon-reload
sudo systemctl restart myapp

Сервіс довго зупиняється

# Перевірити TimeoutStopSec
# Або примусово
sudo systemctl kill myapp

Безпека

[Service]
# Не дозволяти отримувати нові привілеї
NoNewPrivileges=yes

# Захистити системні директорії
ProtectSystem=strict
# strict = /usr, /boot, /efi тільки для читання
# full = + /etc тільки для читання

# Захистити домашні директорії
ProtectHome=yes

# Дозволити запис тільки в конкретні директорії
ReadWritePaths=/opt/myapp/data
ReadWritePaths=/var/log/myapp

# Приватна мережа (ізоляція)
PrivateNetwork=yes

# Приватний /tmp
PrivateTmp=yes

Корисні команди

# Де знаходиться unit файл
systemctl show -p FragmentPath nginx

# Залежності сервісу
systemctl list-dependencies nginx

# Час завантаження сервісів
systemd-analyze blame

# Графік завантаження
systemd-analyze plot > boot.svg

# Перевірити конфіг
systemd-analyze verify /etc/systemd/system/myapp.service

# Очистити failed статуси
sudo systemctl reset-failed

Див. також

Шлях: reference/systemd-services.md

UMTC Wiki © 2026 | Ukrainian Military Tactical Communications