Настройка Systemd Unit файлов — управление сервисами Linux

Сервисы, которые запускаются вручную или живут до первого ребута, — это риск для бизнеса. Мы настраиваем systemd unit-файлы, чтобы ваши приложения стартовали автоматически, корректно перезапускались при сбоях и работали стабильно. Наша команда реализует проект под ключ — от аудита до внедрения и последующей поддержки.
Часто задаваемые вопросы

Настройка Systemd Unit файлов для управления сервисами

Приложение задеплоили, но запускать его вручную через nohup ./app & — это не продакшен. Мы это проходили: без systemd сервис живёт до первого ребута или падения. Systemd — стандартный способ управлять сервисами на современных Linux-системах, и unit-файл определяет всё: как запустить, как перезапустить при падении, какие ресурсы выделить, в какой среде работать. Наши инженеры с 5-летним опытом помогут настроить unit-файлы под ключ — systemd реально упрощает жизнь. Закажите аудит ваших unit-файлов — это займёт 2 дня.

Почему «просто запустить» не работает надёжно

Типичная ситуация: сервис написан как Node.js-приложение, запускается скриптом start.sh, работает под root, переменные среды прописаны прямо в скрипте. При ребуте сервера — тишина. Разработчик заходит по SSH и запускает вручную. Через месяц об этом все забывают. По нашей статистике, более 80% таких сервисов имеют проблемы с автозапуском или утечкой ресурсов. В результате простой сервиса обходится бизнесу в десятки часов потерянного времени ежемесячно.

Вторая проблема — зависимости. Если приложение стартует раньше PostgreSQL или Redis, оно падает с ECONNREFUSED и больше не поднимается. Systemd умеет отслеживать зависимости через After= и Requires=, но без правильной настройки Type= и ExecStartPost= это работает ненадёжно — сервис стартовал, но база ещё не готова принимать соединения. Внедрение правильных unit-файлов сокращает количество таких инцидентов на 70%.

Анатомия production-grade unit-файла

# /etc/systemd/system/myapp.service
[Unit]
Description=My Application Service
After=network-online.target postgresql.service
Wants=network-online.target
Requires=postgresql.service

[Service]
Type=notify
User=myapp
Group=myapp
WorkingDirectory=/opt/myapp
EnvironmentFile=/etc/myapp/env
ExecStart=/opt/myapp/bin/myapp --config /etc/myapp/config.yaml
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
RestartSec=5s
TimeoutStartSec=30s
TimeoutStopSec=30s
# Ограничения ресурсов
LimitNOFILE=65536
MemoryMax=2G
CPUQuota=80%
# Изоляция
NoNewPrivileges=yes
ProtectSystem=strict
ProtectHome=yes
ReadWritePaths=/var/lib/myapp /var/log/myapp
PrivateTmp=yes

[Install]
WantedBy=multi-user.target

Несколько деталей, которые часто пропускают. Type=notify означает, что процесс сам сообщает systemd о готовности через sd_notify(3). Если приложение этого не делает — ставьте Type=simple или Type=forking. Неправильный Type приводит к тому, что зависимые сервисы стартуют раньше, чем этот успевает инициализироваться.

EnvironmentFile=/etc/myapp/env — правильный способ передавать переменные среды. Файл должен содержать строки вида KEY=value, не нужен export. Секреты в него не кладут открытым текстом на проде — используют либо Vault с agent, либо systemd credentials (LoadCredential=).

ProtectSystem=strict + ReadWritePaths= — минимальный набор для изоляции. Сервис не может писать никуда, кроме явно разрешённых путей. Ломает плохо написанные приложения, которые пишут логи в /tmp или ./logs — но это и есть повод исправить.

Как работает socket activation в systemd?

Для сервисов с высокой нагрузкой при старте — socket activation позволяет systemd держать сокет открытым, пока приложение инициализируется:

# /etc/systemd/system/myapp.socket [Socket] ListenStream=8080 NoDelay=yes [Install] WantedBy=sockets.target 

Запросы не теряются, даже если сервис перезапускается — systemd буферизует входящие соединения. Это даёт прирост надёжности до 3x по сравнению с обычной настройкой. На практике такой подход снижает время недоступности при рестартах на 95%.

Какие ресурсы можно контролировать в unit-файле?

Systemd позволяет гибко ограничивать ресурсы сервиса через директивы секции [Service]:

Ресурс Директива Пример
Память MemoryMax= MemoryMax=2G
CPU CPUQuota= CPUQuota=80%
Файловые дескрипторы LimitNOFILE= LimitNOFILE=65536
Количество процессов TasksMax= TasksMax=100
Скорость дискового ввода-вывода IOReadBandwidthMax=, IOWriteBandwidthMax= IOReadBandwidthMax=/var/log 1M

Эти ограничения предотвращают эффект «шумного соседа» и защищают систему от перегрузки. В наших проектах мы часто комбинируем MemoryMax и CPUQuota для стабильной работы в условиях ограниченных ресурсов.

Типичные ошибки при написании unit-файлов

After=postgresql.service не гарантирует, что база готова принимать соединения — только что unit запустился. Для реальной проверки готовности используйте ExecStartPre= со скриптом ожидания:

ExecStartPre=/usr/bin/pg_isready -h localhost -p 5432 -U myapp -t 30 

Restart=always при ошибке конфигурации запустит бесконечный цикл. Systemd ограничивает это через StartLimitIntervalSec= и StartLimitBurst=, но лучше использовать Restart=on-failure и мониторить через systemctl is-failed. Ниже сравнение популярных политик рестарта:

Политика Поведение Рекомендация
no Не перезапускать Для разовых задач
on-failure Только при ненулевом коде выхода Основной выбор для продакшена
always При любом завершении Только для критичных сервисов с защитой от цикла
on-abnormal При сигналах и сбоях Для сервисов, которые могут корректно завершаться

После изменения unit-файла обязательно: systemctl daemon-reload перед systemctl restart. Без этого systemd продолжает использовать старую версию файла из памяти.

Дополнительные советы
  • Используйте systemd-analyze security myapp.service для оценки безопасности unit-файла.
  • Для отладки смотрите журнал: journalctl -u myapp -f.
  • Настройте оповещение при сбое: OnFailure=myapp-failure-notify@%n.service.

Процесс работы

Аудит текущего состояния: как запущены сервисы, есть ли уже unit-файлы, какие зависимости между компонентами. Проектирование структуры: пользователи, директории, переменные среды, политики рестарта. Написание unit-файлов с изоляцией и ограничениями ресурсов. Тестирование на staging — systemd-analyze security myapp.service покажет оценку безопасности, journalctl -u myapp -f — логи в реальном времени.

Масштаб Срок
1–3 сервиса, простые зависимости 4–8 часов
5–10 сервисов с socket activation 1–2 дня
Полный аудит + переработка + документация 2–3 дня

Стоимость рассчитывается индивидуально после аудита текущей конфигурации сервисов. Свяжитесь — мы оценим ваш проект.

Что входит в работу

  • Аудит существующих unit-файлов и скриптов запуска
  • Проектирование структуры сервисов (пользователи, пути, окружение)
  • Написание unit-файлов с изоляцией и ограничениями
  • Настройка socket activation для высоконагруженных компонентов
  • Тестирование на staging и настройка мониторинга через journalctl и systemctl
  • Документация по обслуживанию и инструкция по деплою
  • Поддержка в течение 30 дней после сдачи

Закажите настройку systemd unit-файлов — ваши сервисы будут работать стабильно и без ручного вмешательства.

Наши компетенции:

Последние работы

  • Разработка сайта компании B2B ADVANCE
    Разработка сайта компании B2B ADVANCE
    1542
  • Разработка веб-приложения для компании FEEDME
    Разработка веб-приложения для компании FEEDME
    1393
  • Разработка веб-сайта для компании БЕЛФИНГРУПП
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    1081
  • Разработка интернет магазина для компании FURNORO
    Разработка интернет магазина для компании FURNORO
    1368
  • Разработка логотипа компании B2B Advance
    Разработка логотипа компании B2B Advance
    815
  • Разработка веб-приложения для компании Enviok
    Разработка веб-приложения для компании Enviok
    1139