Ansible: рестарт контейнеров переведён на handlers

- caddyproxy, netdata, authelia, bifrost, remembos: конфиг-задачи нотифаят
  handler "Restart application" вместо безусловного или условного рестарта
- ansible.cfg: force_handlers, иначе упавший прогон теряет notify и рестарт,
  применяющий правку конфига, не случится уже никогда
- authelia рестартит только authelia_app, чтобы не сбрасывать сессии в redis
This commit is contained in:
av
2026-07-24 21:05:27 +03:00
parent 1cf660b4fd
commit 9c156df0c7
10 changed files with 75 additions and 40 deletions
+1 -1
View File
@@ -21,7 +21,6 @@ _(sec-ревью)_ — три независимых security-ревью на м
- [Убрать группу `docker` у сервисных пользователей](service-users-docker-group.md) — `docker` = root на хосте; ~все app-аккаунты фактически root, изоляция «юзер на сервис» обнуляется _(sec-ревью)_
- [Изолировать/запаролить сессионный redis Authelia](authelia-redis-isolation.md) — стор сессий SSO в общей сети без пароля; запись в него = hijack SSO всех сервисов _(sec-ревью)_
- [Алерты на проблемные контейнеры](container-alerts.md) — wakapi крутился в restart-loop несколько дней незамеченным; healthcheck в compose + алерты Netdata
- [Рестарт контейнеров через handlers](ansible-handlers-restart.md) — `state: restarted` выполняется безусловно на каждом прогоне (лишний downtime), нет ни одного handler _(ансибл-ревью)_
## Средний
@@ -36,6 +35,7 @@ _(sec-ревью)_ — три независимых security-ревью на м
- [Gitea runner on-demand в Yandex Cloud](gitea-runner-on-demand.md) — раннер активен только во время сборки; webhook→Cloud Function стартует ВМ, probe/decide гасят по idle; экономия ~95%
- [Синхронизация общих Ansible-ролей](shared-roles-sync.md) — `owner`/`eget`/`secrets` дублируются между репозиториями и дрейфуют; канон в ansible-shared + rsync-таски invoke
- [Уведомления о размере приложений и диске](disk-usage-alerts.md) — алерты на заполнение диска и аномальный рост data-томов; сервер ресурсно ограничен _(tududi)_
- [Handlers рестарта для оставшихся приложений](handlers-remaining-apps.md) — apprise/dashboard/transcriber/miniflux монтируют конфиг в контейнер, но рестарта нет вовсе; правка конфига не подхватывается
- [Composable-роль `backup`](ansible-backup-role.md) — бэкап — самый чистый шов для extraction (одинаков у всех, различается только список targets) _(ансибл-ревью)_
- [Точечные фиксы идемпотентности и баг имени play](ansible-quick-fixes.md) — быстрые правки: имя play в wanderer, `changed_when` в netdata/eget, backup-targets через template _(ансибл-ревью)_
-20
View File
@@ -1,20 +0,0 @@
# Рестарт контейнеров через handlers, а не безусловно
**Приоритет:** высокий
Ни в одном плейбуке нет `handlers:`. Вместо этого задача `state: restarted`
выполняется **всегда** — рестартит контейнер на каждом прогоне даже без
изменений (`playbook-caddyproxy.yml:106`, `playbook-netdata.yml:143`,
`playbook-authelia.yml:92`): не идемпотентно, лишний downtime. В
`playbook-gitea.yml` рестарта нет вовсе — несогласованность. Канонический
паттерн: шаблон конфига `notify`-ит handler, который делает
`docker_compose_v2: state: restarted` только при реальном изменении. Внедряется
инкрементально, по одному сервису. Заодно убрать мёртвый
`docker_compose_file_result` в `playbook-memos.yml:76` (регистрируется, нигде не
используется — задумывался под `when`/`notify`).
Топ-приоритет ансибл-ревью. Полный контекст:
[docs/drafts/ansible-review.md](../drafts/ansible-review.md) §3.
Связано: playbook-caddyproxy.yml, playbook-netdata.yml, playbook-authelia.yml,
playbook-gitea.yml, playbook-memos.yml.
+30
View File
@@ -0,0 +1,30 @@
# Handlers рестарта для оставшихся приложений
**Приоритет:** средний
Паттерн `handlers` + `notify` внедрён в caddyproxy, netdata, authelia, bifrost,
remembos (см. задачу `ansible-handlers-restart`, закрыта). Остались плейбуки, где
конфиг bind-моунтится в контейнер, но рестарта нет **вообще** — правка конфига без
изменения docker-compose.yml не подхватывается до следующего пересоздания
контейнера:
- `playbook-apprise.yml``server.cfg``config_dir:/config`.
- `playbook-dashboard.yml``config/*.yaml``config_dir:/app/config`.
- `playbook-transcriber.yml``config.toml` bind-моунтится **отдельным файлом**
(`{{ config_file }}:/config/config.toml:ro`). Худший случай: `template`
перезаписывает файл с новым inode, и контейнер продолжает видеть старый до
рестарта.
- `playbook-miniflux.yml` — файлы секретов роли `secrets``secrets_dir:/secrets:ro`,
читаются через `*_FILE` при старте.
Заодно проверить `playbook-goaccess.yml`: конфиг там не монтируется, но
`Dockerfile`/`entrypoint.sh` меняются без изменения compose-файла — надо
убедиться, что `build: always` действительно пересоздаёт контейнер.
Отдельный кандидат: caddy сейчас перезапускается целиком, хотя умеет
`caddy reload` — применение Caddyfile без разрыва соединений на реверс-прокси,
через который идёт весь трафик. В `playbook-caddyproxy.yml` для этого уже лежит
закомментированный блок с `docker_compose_v2_exec`.
Связано: playbook-apprise.yml, playbook-dashboard.yml, playbook-transcriber.yml,
playbook-miniflux.yml, playbook-goaccess.yml, playbook-caddyproxy.yml.