Плохой конфиг не должен запускать сервис: добавляем ExecStartPre

После доставки конфигурации приложение успевает создать часть выходных файлов и только затем обнаруживает опечатку. Если программа предоставляет отдельный режим проверки, его можно включить перед основным запуском. Так ошибка будет видна в журнале ещё до начала обычной обработки.

Выбрать настоящую проверку

Нужен поддерживаемый валидатор именно этого приложения: разбор синтаксиса, обязательных параметров и доступных безопасных проверок. Команда test -f подтверждает только существование файла. Она не обнаружит неверный параметр и не заменяет проверку содержимого. Сначала выполните валидатор на стенде от будущего сервисного пользователя.

[Service]
User=reportbot
ExecStartPre=/usr/local/bin/report-worker --check-config /etc/report/worker.conf
ExecStart=/usr/local/bin/report-worker --config /etc/report/worker.conf

report-worker — условное приложение; его параметры нужно заменить реальным документированным интерфейсом вашей программы. ExecStartPre запускается перед основной командой. Ненулевой выход подготовительной команды обычно прерывает запуск; префикс «-» у команды меняет отношение к ошибке и здесь не нужен.

Увидеть правильный источник ошибки

systemctl show report.service -p Result -p ExecStartPre -p ExecMainStatus
journalctl -u report.service -b --no-pager
systemctl cat report.service

В учебном сценарии валидатор пишет «unknown key: workers_count» и выходит с кодом 2. Основной процесс ещё не запускался. Поэтому ExecMainStatus сам по себе не даёт полного объяснения: смотрите результат подготовительной команды и соответствующие строки журнала. Исправьте параметр, повторите проверку и только затем запускайте основную обработку.

Команды выполняются в контексте настроек службы, включая пользователя и ограничения, с оговорёнными в systemd возможностями специальных префиксов. Это полезно: валидация от root могла бы прочитать файл, недоступный reportbot. Поведение этапов описано в systemd.service.

Не превращать подготовку в фоновую службу

ExecStartPre предназначен для завершающихся команд. Запускать в нём долгоживущий процесс в фоне и рассчитывать, что он будет сопровождать основное приложение, неправильно: systemd завершает оставшиеся процессы подготовительного этапа перед следующим шагом. Для самостоятельной работы создайте отдельную службу с явной зависимостью.

Также не помещайте сюда необратимую миграцию без собственного плана. Служба может запускаться повторно после ошибки или перезагрузки, поэтому подготовительная команда должна допускать выбранную повторяемость. Проверка конфига хороша тем, что обычно не меняет состояние приложения.

Проверить границу применимости

Успешная валидация не фиксирует файл навсегда. Между проверкой и чтением основным процессом конфигурацию могут заменить. Для управляемой доставки используйте согласованный способ публикации и не меняйте файл посреди запуска. Если программа имеет единый безопасный механизм reload, изучите его отдельно: ExecStartPre не выполняется при каждом reload автоматически.

В тесте нужны корректный конфиг, синтаксическая ошибка и недоступный файл. Для каждого сохраните ожидаемый результат и сообщение журнала. Тогда порядок станет полезным барьером, а не декоративной строкой unit.

Посмотрите программу Linux и Bash для DevOps-инженеров. Работа с systemd и диагностикой сервиса помогает превратить команды подготовки в понятные этапы запуска с проверяемыми результатами.

Ещё по теме

Продолжить на практике

  • Linux и Bash для DevOps-инженеров ↗

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