Переопределение через drop-in не применяется
Переопределения лежат в каталоге вида /etc/systemd/system/myapp.service.d/*.conf и дополняют основной файл. Если правка не действует, причин обычно три: не перечитана конфигурация, файл назван неверно, либо параметр требует предварительного сброса.
Что это значит
Особенность, из-за которой теряют больше всего времени: параметры со списком значений (ExecStart=, Environment=, After=) в переопределении добавляются к существующим, а не заменяют их. Чтобы заменить, нужно сначала очистить значение пустой строкой.
Вероятные причины
По порядку: сверху то, что встречается чаще.
-
Не выполнена перезагрузка конфигурации
Файлы переопределений читаются так же, как основной unit: изменения на диске сами по себе ничего не меняют.
-
Файл переопределения назван неверно
systemd читает в каталоге
.dтолько файлы с расширением.conf. Файлoverrideили10-override.conf.bakбудет проигнорирован. -
Параметр со списком не сброшен перед заменой
Для
ExecStart=в обычной службе это приводит к ошибке «service has more than one ExecStart», а для списков зависимостей — к добавлению вместо замены. -
Переопределение попало не в тот unit
Каталог должен называться точно по имени unit, включая расширение:
myapp.service.d, а неmyapp.d. Для шаблонных unit есть свои правила именования.
Диагностика
Команды идут в том порядке, в котором их стоит выполнять: каждая следующая проверяет то, что осталось после предыдущей.
Печатает основной файл и все применённые переопределения с путями. Если вашего файла тут нет, он не читается.
systemctl cat myapp.serviceИтоговые значения после слияния: видно, заменилось значение или добавилось.
systemctl show myapp.service -p ExecStart -p Environment -p AfterПоказывает все переопределения в системе и что именно они меняют.
sudo systemd-delta --type=extended | head -20Решение
Решение своё для каждой причины. Сначала определите, какая из них ваша, — иначе правки наложатся друг на друга.
- Почему происходит
- Файлы переопределений читаются так же, как основной unit: изменения на диске сами по себе ничего не меняют.
- Как проверить
-
Посмотрите, нужна ли перезагрузка, и что systemd считает действующим.
systemctl show myapp.service -p NeedDaemonReload systemctl cat myapp.service
- Как исправить
-
Выполните перезагрузку конфигурации и перезапустите службу.
sudo systemctl daemon-reload && sudo systemctl restart myapp.service
- Почему происходит
- systemd читает в каталоге
.dтолько файлы с расширением.conf. Файлoverrideили10-override.conf.bakбудет проигнорирован.
- Как проверить
-
Посмотрите содержимое каталога.
sudo ls -l /etc/systemd/system/myapp.service.d/
- Как исправить
-
Переименуйте файл так, чтобы он заканчивался на
.conf. Удобнее не создавать файлы вручную, а пользоватьсяsystemctl edit.
- Почему происходит
- Для
ExecStart=в обычной службе это приводит к ошибке «service has more than one ExecStart», а для списков зависимостей — к добавлению вместо замены.
- Как проверить
-
Посмотрите итоговое значение параметра.
systemctl show myapp.service -p ExecStart -p After
- Как исправить
-
Сначала очистите значение пустым присваиванием, затем задайте новое.
[Service] ExecStart= ExecStart=/usr/local/bin/myapp --new-flag
- Почему происходит
- Каталог должен называться точно по имени unit, включая расширение:
myapp.service.d, а неmyapp.d. Для шаблонных unit есть свои правила именования.
- Как проверить
-
Сверьте имя каталога с именем unit.
systemctl cat myapp.service | head -3 sudo ls -d /etc/systemd/system/*.d
- Как исправить
-
Переименуйте каталог. Для шаблона правка применяется либо к
myapp@.service.d(всем экземплярам), либо кmyapp@prod.service.d(одному).
Пример вывода
В переопределении задан второй ExecStart без сброса первого. Пример показательный: он собран на тестовой машине специально для этой страницы, а не взят из чужого журнала.
$ sudo systemctl restart myapp.service
Job for myapp.service failed because the control process exited with error code.
systemd[1]: /etc/systemd/system/myapp.service.d/override.conf:2: Service has more than one ExecStart= setting, which is only allowed for Type=oneshot services. Refusing.
systemd[1]: myapp.service: Unit configuration has fatal error, unit will not be started.
Связанные ошибки
- Warning: The unit file … changed on disk Предупреждение о том, что unit-файл изменился на диске: systemd работает со старой версией. Когда нужен daemon-reload.
- Unit file is bad и ошибки разбора unit-файла systemd не может разобрать unit-файл: неизвестные параметры, ошибки в секциях, недопустимые значения. Как найти проблемную строку.
- Unit … not found: unit-файл не найден Сообщение Unit not found при запуске службы: файла нет, не выполнен daemon-reload, опечатка в имени или не указано расширение.
- Service has more than one ExecStart= setting Несколько команд запуска допустимы только при Type=oneshot. Как правильно заменить команду в переопределении.
- Apache: Invalid command — не включён модуль Apache не запускается: директива требует модуль, который не подключён. Как найти нужный модуль и включить.
- Docker: unable to configure the Docker daemon with file daemon.json Демон Docker не запускается из-за ошибки в /etc/docker/daemon.json: неверный JSON или неизвестный ключ.
- Unit is masked: служба запрещена к запуску Сообщение Unit is masked: unit заблокирован ссылкой на /dev/null. Как найти и снять маскировку.
- Unit … has no installation config: не включается автозапуск systemctl enable отказывает: в unit-файле нет секции [Install] или WantedBy. Как включить службу в автозапуск правильно.
Источники
-
systemd.unit(5)
Каталоги *.d, порядок слияния и сброс списочных параметров пустым присваиванием. -
systemd-delta(1)
Просмотр переопределений в системе. -
Воспроизведено на тестовой машине, systemd 255 (Ubuntu 24.04)
Воспроизведено переопределением с двумя ExecStart и файлом без расширения .conf.