After= и Before= в systemd: порядок запуска служб
Задают порядок запуска: After= означает «запускать после того, как перечисленные unit завершат запуск», Before= — обратное. Сами по себе они не требуют, чтобы эти unit вообще запускались.
Что делает
Это самая частая путаница в systemd. Порядок и необходимость — разные вещи. After=postgresql.service не запустит базу и не помешает вашей службе стартовать, если база упала: она просто не будет стартовать раньше. Необходимость задаётся через Requires= или Wants=, и почти всегда их указывают вместе с After=.
Где ставится. В секции [Unit]. Имена перечисляются через пробел, с расширением unit.
Значения
| Значение | Что происходит |
|---|---|
After=network-online.target | запуск после готовности сети. |
After=postgresql.service redis.service | несколько зависимостей через пробел. |
Before=nginx.service | запускаться раньше указанного unit. |
Пример
Порядок и необходимость вместе.
[Unit]
Wants=network-online.target postgresql.service
After=network-online.target postgresql.service
Wants= выражает «пусть запустится», After= — «после него». Без второй строки порядок не гарантирован даже при наличии первой.
Типичные ошибки
After= без Requires= или Wants= не запускает зависимость и не мешает старту при её падении.
Взаимные After= у двух служб создают цикл: systemd разорвёт его, отбросив одну связь.
Имя без расширения (After=postgresql) может не найтись: пишите полное имя.
After=network.target не значит, что сеть работает: для этого есть network-online.target.
Связанные ошибки
- Dependency failed for … и результат 'dependency'Сообщение Dependency failed for: служба не запускалась, потому что упала её зависимость. Как найти настоящего виновника.
- Found ordering cycle: циклическая зависимость при загрузкеsystemd нашёл цикл в порядке запуска и разорвал его, отбросив одну зависимость. Как найти цикл и правильно расставить After и Requires.
- Connection refused в журнале службыСоединение отклонено: служба не может подключиться к базе, кешу или другому сервису. Порядок запуска, адрес, брандмауэр.
- Cannot assign requested address при привязкеОшибка 99 при привязке: адрес не принадлежит машине или ещё не поднят. Разбор с network-online.target и ip_nonlocal_bind.
Рядом стоящие параметры
Где важен на практике
Источники
- systemd.unit(5)
- Воспроизведено на тестовой машине, systemd 255 (Ubuntu 24.04)