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
Див. також¶
- Linux основи — базові команди
- Docker — контейнеризація (альтернатива для сервісів)
- Моніторинг — слідкування за сервісами
Шлях: reference/systemd-services.md