Паттерн: при 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.service | unit фейлится если Docker не стартовал |
Type=oneshot | systemd ждёт завершения 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
donedocker 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директива)
Связано
- nginx 502 после рестарта Docker контейнера — конкретный кейс
- Отключение systemd сервисов через rename в .disabled
Мета
Область:: 00 Linux