[Unit]# ОписаниеDescription=Описаниесервиса
Documentation=man:nginx(8)# ссылки на man/URL/документацию unit’а# Порядок стартаAfter=network.target# стартовать после указанных unit’овBefore=nginx.service# стартовать раньше указанных unit’ов# ЗависимостиRequires=postgresql.service# сильная зависимость; если зависимость не поднимется, сервис тожеWants=network-online.target# мягкая зависимость; systemd попробует поднять, но failure не обязателен для отказаBindsTo=dev-sda1.device# сильная привязка, часто к устройствам/монтированиямPartOf=myapp.target# если основной unit перезапускается/останавливается, этот следует за нимConflicts=shutdown.target# взаимоисключающие unit’ы# Условия запускаConditionPathExists=/etc/myapp.conf
ConditionFileNotEmpty=/etc/myapp.conf
ConditionDirectoryNotEmpty=/var/lib/myapp
AssertPathExists=/data
# Ограничение частоты стартаStartLimitIntervalSec=60# Ограничивает число неудачных запусков за интервал.StartLimitBurst=3[Service]Type=simple# Варианты:# simple — default для многих случаев; ExecStart запущен, service считается стартовавшим почти сразу# exec — похож на simple, но старт считается успешным после успешного execve()# forking — старый daemon mode, когда процесс форкается в фон# oneshot — выполнить команду и выйти# notify — сервис сам сообщает systemd, что готов# notify-reload — notify + отдельная логика reload# dbus — сервис считается готовым, когда зарегистрировал имя на D-Bus# idle — откладывает выполнение до разгрузки очереди jobs# Для современных приложений обычно используют simple, exec, notify, реже forking.# Как выбирать:# - обычный foreground-процесс → Type=simple# - legacy daemon, который сам уходит в фон → Type=forking# - init-скрипт/разовая команда → Type=oneshot# - приложение с sd_notify → Type=notify# Команды запуска/остановкиExecStart=/usr/bin/myapp--config/etc/myapp.conf# главная команда запускаExecStartPre=/usr/bin/test-f/etc/myapp.conf# перед стартомExecStartPost=/usr/bin/loggerstarted# после стартаExecReload=/bin/kill-HUP$MAINPID# что делать при systemctl reloadExecStop=/usr/bin/myapp--stop# как останавливатьExecStopPost=/usr/bin/rm-f/run/myapp.pid# после остановки# ПерезапускRestart=on-failure
# Варианты:# no# on-failure# always# on-abnormal# on-watchdog# on-success# on-abortRestartSec=5RestartSteps=...
RestartMaxDelaySec=...
# ТаймаутыTimeoutStartSec=30# сколько ждать стартаTimeoutStopSec=20# сколько ждать остановкиTimeoutAbortSec=15RuntimeMaxSec=1h# максимум времени жизни сервисаRuntimeRandomizedExtraSec=30WatchdogSec=30# интервал watchdog для сервисов, умеющих общаться с systemd# Пользователь, группа, umaskUser=myuser
Group=mygroup
SupplementaryGroups=docker# дополнительные группыUMask=0027# маска прав для создаваемых файлов# Рабочий каталог и окружениеWorkingDirectory=/opt/myapp# cwd процессаEnvironment=APP_ENV=prod# переменные окруженияEnvironment=PORT=8080EnvironmentFile=/etc/myapp.env# читать env из файлаPassEnvironment=HTTP_PROXYHTTPS_PROXY# пробросить переменные из manager environmentUnsetEnvironment=DEBUG# удалить переменные из окружения процесса# PID-файлPIDFile=/run/myapp.pid# Обычно нужно только для Type=forking, когда основной PID надо узнать по pidfile.# stdout/stderr и журналStandardOutput=journal
StandardError=journal
SyslogIdentifier=myapp
LogLevelMax=info
# Завершение процессовKillMode=control-group# как убивать процессы сервисаKillSignal=SIGTERM# основной сигнал остановкиFinalKillSignal=SIGKILL# если не завершился вовремяSendSIGKILL=yes# слать ли SIGKILL в концеSendSIGHUP=no
# Минимизация привилегийNoNewPrivileges=yes
PrivateTmp=yes
PrivateDevices=yes
ProtectSystem=full
ProtectHome=yes
ProtectKernelTunables=yes
ProtectKernelModules=yes
ProtectControlGroups=yes
RestrictSUIDSGID=yes
LockPersonality=yes
MemoryDenyWriteExecute=yes
RestrictRealtime=yes
# Фильтрация системных вызовов и capabilityCapabilityBoundingSet=CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_BIND_SERVICE
SystemCallFilter=@system-service
SystemCallArchitectures=native
RestrictAddressFamilies=AF_INETAF_INET6AF_UNIX
# Доступ к ФСReadOnlyPaths=/etc
ReadWritePaths=/var/lib/myapp/var/log/myapp
InaccessiblePaths=/home
TemporaryFileSystem=/tmp:size=100M
BindPaths=/srv/data:/data
# Контроль ресурсовMemoryMax=500M
MemoryHigh=300M
CPUQuota=50%
CPUWeight=200TasksMax=512IOWeight=200[Install]WantedBy=multi-user.target# при enable создается зависимость от target# multi-user.target — обычный серверный multi-user режим# graphical.target — графический режим# default.target — target по умолчанию через symlink/alias логики systemdAlso=myapp-worker.service# вместе включать/выключать дополнительные unit’ыAlias=myapp.service# альтернативное имя unit’аRequiredBy=some.target# более сильная версия