Паттерн: при boot системы один сервис должен подождать пока другой контейнер станет healthy, потом сделать действие (рестарт, миграция, оповещение). Реализуется через systemd oneshot unit с After=docker.service + polling-цикл.

Шаблон

# /etc/systemd/system/post-docker-action.service
[Unit]
Description=Action after Docker containers stabilize
After=docker.service
Requires=docker.service
 
[Service]
Type=oneshot
ExecStart=/bin/bash -c 'until docker inspect CONTAINER --format "{{.State.Health.Status}}" 2>/dev/null | grep -q healthy; do sleep 5; done; YOUR_COMMAND'
TimeoutStartSec=300
RemainAfterExit=yes
StandardOutput=journal
 
[Install]
WantedBy=multi-user.target

Установка:

sudo systemctl daemon-reload
sudo systemctl enable post-docker-action.service

Разбор по элементам

ОпцияЧто делает
After=docker.serviceстартует ПОСЛЕ Docker — гарантирует что docker команда доступна
Requires=docker.serviceunit фейлится если Docker не стартовал
Type=oneshotsystemd ждёт завершения ExecStart, не считает «активным» процесс
RemainAfterExit=yesпосле успешного завершения unit видится как active (exited) — НЕ перезапускается
TimeoutStartSec=300максимум 5 мин на завершение (если контейнер так и не стал healthy — fail)
WantedBy=multi-user.targetстартует при обычном boot

Polling-цикл

until docker inspect CONTAINER --format '{{.State.Health.Status}}' 2>/dev/null | grep -q healthy; do
  sleep 5
done

docker inspect возвращает healthy, unhealthy, starting, none. Цикл ждёт точное healthy.

2>/dev/null глотает ошибки на случай если контейнер ещё не существует (Docker не успел его создать).

Конкретные применения

  • nginx-после-Docker — рестарт nginx когда upstream-контейнеры готовы, fix 502
  • DB-миграцияflyway migrate после того как PostgreSQL healthy
  • Уведомлениеcurl -X POST $WEBHOOK после всех healthcheck’ов
  • Backup hook — запуск pre-backup команды когда приложение готово

Ограничения

  • Один контейнер в условии — на массовое ожидание нужно расширять (for c in ...; do until ...; done)
  • Не реагирует на post-boot рестарты контейнеров (только при boot системы)
  • Healthcheck должен быть определён в compose/Dockerfile (HEALTHCHECK директива)

Связано


Мета

Область:: 00 Linux