Systemd.service вместо Docker? Пересмотр стратегии развертывания веб‑приложений на Linux

В последние годы фраза «развертывание = Docker + контейнерная оркестрация (Kubernetes, ECS и т.д.)» стала почти общепринятой. Поэтому подход, при котором веб‑приложение просто запускается как процесс + сервис systemd, иногда выглядит устаревшим.

Однако в реальности:

  • однократное веб‑приложение
  • небольшая команда / простая инфраструктура
  • on‑premise или строго регулируемая среда

— всё ещё часто делает развертывание через systemd более простым, надёжным и удобным для эксплуатации.

В этой статье мы разберём, какие преимущества имеет systemd по сравнению с Docker при развертывании веб‑приложений, и в каких ситуациях он оказывается более полезным.


1. Кратко о systemd и Docker



Docker

  • упаковывает приложение в образ
  • запускает его в контейнере
  • «оболочка среды» → одинаковое поведение везде

Systemd

  • базовая система init в современных дистрибутивах Linux
  • запускает сервисы при загрузке, перезапускает их при падении, управляет логами
  • описывается через файлы‑юниты *.service

Docker — инструмент для изоляции среды, а systemd — инструмент управления процессами в Linux. Они не конкурируют, а часто используются совместно: systemd управляет демоном Docker, а внутри контейнера может работать собственный systemd.

В этой статье мы сосредоточимся на полностью без Docker: развертывание и эксплуатация через systemd.


2. Преимущества развертывания через systemd.service

2‑1. Простота: убираем один слой

С Docker добавляются:

  • демон Docker
  • пайплайн сборки образов
  • реестр образов
  • управление правами и ресурсами контейнера

А при systemd:

  • устанавливаем нужный рантайм (Python/Node/Java и т.д.)
  • размещаем код приложения
  • регистрируем сервис systemd

Это относительно простая архитектура, особенно для небольших проектов.

2‑2. Естественная интеграция с Linux

  • Логиjournalctl -u myapp.service
  • Автозапускsystemctl enable myapp.service
  • Ограничения ресурсовMemoryMax, CPUQuota
  • Управление зависимостямиAfter=network.target, After=postgresql.service

При Docker нужно отдельно отслеживать логи, ресурсы и сетевые настройки контейнера.

2‑3. Меньше накладных расходов

Docker сам по себе не слишком тяжёл, но обычно сопровождается:

  • накоплением слоёв образов → рост диска
  • лишними запущенными контейнерами
  • управлением логами и томами

Systemd требует только ОС + рантайм + код, что особенно важно в ограниченных ресурсах.

2‑4. Прямой доступ к сети

Контейнеры используют собственные IP‑адреса и порты, а также маппинг портов. Systemd привязывается напрямую к IP/порту хоста, что упрощает отладку:

  • «Открыт ли порт?»
  • «Блокирует ли firewall?»
  • «Конфликтует ли с другим сервисом?»

2‑5. Ограниченные возможности Docker

В некоторых средах Docker запрещён:

  • финансовые, государственные, медицинские учреждения
  • политики запрещают контейнеры
  • изоляция от внешних реестров

Тогда единственный вариант – OS + systemd.


3. Пример развертывания через systemd.service



Предположим, у нас приложение на Django/Flask, запускаемое через gunicorn.

3‑1. Файл юнита

/etc/systemd/system/myapp.service:

[Unit]
Description=My Web Application (Gunicorn)
After=network.target

[Service]
User=www-data
Group=www-data
WorkingDirectory=/srv/myapp
EnvironmentFile=/etc/myapp.env
ExecStart=/usr/bin/gunicorn \
    --workers 4 \
    --bind 0.0.0.0:8000 \
    config.wsgi:application

Restart=on-failure
RestartSec=5

# Пример ограничений (необязательно)
# MemoryMax=512M
# CPUQuota=50%

[Install]
WantedBy=multi-user.target

3‑2. Переменные окружения

/etc/myapp.env:

DJANGO_SETTINGS_MODULE=config.settings.prod
SECRET_KEY=super-secret-key
DATABASE_URL=postgres://...

3‑3. Команды управления

# Регистрация и автозапуск
sudo systemctl enable myapp.service

# Запуск/остановка/перезапуск
sudo systemctl start myapp.service
sudo systemctl restart myapp.service
sudo systemctl stop myapp.service

# Статус и логи
sudo systemctl status myapp.service
sudo journalctl -u myapp.service -f

Для тех, кто уже знаком с Linux‑сервером, это почти мгновенное развертывание.


4. Когда systemd предпочтительнее Docker

  1. Один или несколько простых сервисов – без сложной оркестрации.
  2. Небольшое количество серверов (1‑5 машин).
  3. Команда, привыкшая к Linux‑сервисамsystemctl, journalctl, logrotate.
  4. Строго регулируемые среды – финансовые, государственные, медицинские.
  5. Низкие ресурсы – ограниченный диск/память.
  6. Требуется быстрый доступ к отладкеstrace, perf на хост‑процессе.

5. Когда Docker всё же лучше

  • Много сервисов (веб + воркеры + крон + БД).
  • Необходима одинаковая среда в dev/stage/prod.
  • Частые деплои и масштабирование.
  • Интеграция с CI/CD.

В таких случаях Docker обеспечивает единообразие и упрощает развертывание.


image

6. Итог: главное – контекст

Развертывание через Docker не является обязательным, а systemd не всегда хуже. Выбирайте инструмент, исходя из:

  • масштаба и сложности приложения;
  • инфраструктурных ограничений;
  • опыта команды;
  • требований к изоляции и безопасности.

Если ваш сервис прост, инфраструктура небольшая и вы хотите минимизировать накладные расходы, systemd – отличное решение. Если же вам нужна гибкость, масштабируемость и единообразие среды, Docker будет предпочтительнее.


7. Заключение

В конечном счёте, инструмент – это средство. Главное, чтобы он облегчал жизнь команды и обеспечивал надёжную эксплуатацию. Не стоит автоматически ставить Docker в качестве «обязательного» решения; иногда простота systemd будет более продуктивной.