docker-socket-proxy (tecnativa/docker-socket-proxy:0.3.0) в docker-compose.yml: CONTAINERS=1, POST=0, сокет смонтирован read-only только в него. Бот ходит на http://docker-proxy:2375.
app/runtime/docker.py — read-only клиент: список, inspect, stats, logs (демультиплексирование потока). Видны только контейнеры с меткой tgit.managed=true; по чужому id (Vobot, meditron на том же хосте) запрос даже не уходит.
app/runtime/checks.py + config/checks.yaml — S-3: запущен · Docker health · рестарты за 5 мин не растут · CPU/RAM ниже порога · нет ошибок в логе за 5 мин · HTTP-проба по метке tgit.health_url. Каждая проверка со своим таймаутом: упавшая или зависшая даёт ❌ с причиной, отчёт всегда полный.
app/runtime/snapshots.py — раз в 15 с container_snapshots (рестарты, CPU, RAM, health); нужно проверке рестартов и алертам #15.
Бот (app/bot/routers/status.py): список с 🟢/🟡/🔴/⚪ (S-1), карточка — состояние, health, аптайм, рестарты, CPU/RAM от лимита, ревизия, время деплоя (S-2), «🩺 Запустить проверки» для всех или одного контейнера (S-3), «🔄 Обновить» (S-4).
infra/deploy/remote.sh ставит на контейнер бота метки tgit.sha и tgit.deployed_at.
Попутно: имя джоба CD без неотрисованного выражения ${{ … }}.
Не сделано: S-5 «♻️ Перезапустить» (P2) — нужен runner (#13), прокси POST не пропускает.
Как проверено
178 тестов (40 новых): фейковый Docker API на httpx.MockTransport, GET-only как прокси; покрытие 91%, ruff, mypy strict.
Смоук против настоящего Docker через тот же прокси: здоровый и unhealthy контейнеры, ошибка в stderr, POST → 403.
После мержа CD развернёт прокси на сервере — проверю «Статус» в боте.
Closes #14
## Что сделано
- **docker-socket-proxy** (`tecnativa/docker-socket-proxy:0.3.0`) в `docker-compose.yml`: `CONTAINERS=1`, `POST=0`, сокет смонтирован read-only только в него. Бот ходит на `http://docker-proxy:2375`.
- **`app/runtime/docker.py`** — read-only клиент: список, inspect, stats, logs (демультиплексирование потока). Видны только контейнеры с меткой `tgit.managed=true`; по чужому id (Vobot, meditron на том же хосте) запрос даже не уходит.
- **`app/runtime/checks.py`** + **`config/checks.yaml`** — S-3: запущен · Docker health · рестарты за 5 мин не растут · CPU/RAM ниже порога · нет ошибок в логе за 5 мин · HTTP-проба по метке `tgit.health_url`. Каждая проверка со своим таймаутом: упавшая или зависшая даёт ❌ с причиной, отчёт всегда полный.
- **`app/runtime/snapshots.py`** — раз в 15 с `container_snapshots` (рестарты, CPU, RAM, health); нужно проверке рестартов и алертам #15.
- **Бот** (`app/bot/routers/status.py`): список с 🟢/🟡/🔴/⚪ (S-1), карточка — состояние, health, аптайм, рестарты, CPU/RAM от лимита, ревизия, время деплоя (S-2), «🩺 Запустить проверки» для всех или одного контейнера (S-3), «🔄 Обновить» (S-4).
- `infra/deploy/remote.sh` ставит на контейнер бота метки `tgit.sha` и `tgit.deployed_at`.
- Попутно: имя джоба CD без неотрисованного выражения `${{ … }}`.
Не сделано: S-5 «♻️ Перезапустить» (P2) — нужен runner (#13), прокси POST не пропускает.
## Как проверено
- 178 тестов (40 новых): фейковый Docker API на `httpx.MockTransport`, GET-only как прокси; покрытие 91%, ruff, mypy strict.
- Смоук против настоящего Docker через тот же прокси: здоровый и unhealthy контейнеры, ошибка в stderr, POST → 403.
- После мержа CD развернёт прокси на сервере — проверю «Статус» в боте.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
- docker-socket-proxy в Compose (только GET /containers/*), сокет только у него
- app/runtime/docker.py: read-only клиент; видны только контейнеры с меткой
tgit.managed=true, чужие id отклоняются до запроса
- app/runtime/checks.py: running, health, рестарты за окно, CPU/RAM, ошибки
в логе, HTTP-проба; у каждой проверки свой таймаут, отчёт всегда полный
- app/runtime/snapshots.py: снапшоты раз в 15 с в container_snapshots
- бот: список с 🟢🟡🔴⚪, карточка, «🩺 Запустить проверки», «🔄 Обновить»
- деплой ставит метки tgit.sha / tgit.deployed_at на контейнер бота
- имя джоба CD без неотрисованного выражения
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Closes #14
Что сделано
tecnativa/docker-socket-proxy:0.3.0) вdocker-compose.yml:CONTAINERS=1,POST=0, сокет смонтирован read-only только в него. Бот ходит наhttp://docker-proxy:2375.app/runtime/docker.py— read-only клиент: список, inspect, stats, logs (демультиплексирование потока). Видны только контейнеры с меткойtgit.managed=true; по чужому id (Vobot, meditron на том же хосте) запрос даже не уходит.app/runtime/checks.py+config/checks.yaml— S-3: запущен · Docker health · рестарты за 5 мин не растут · CPU/RAM ниже порога · нет ошибок в логе за 5 мин · HTTP-проба по меткеtgit.health_url. Каждая проверка со своим таймаутом: упавшая или зависшая даёт ❌ с причиной, отчёт всегда полный.app/runtime/snapshots.py— раз в 15 сcontainer_snapshots(рестарты, CPU, RAM, health); нужно проверке рестартов и алертам #15.app/bot/routers/status.py): список с 🟢/🟡/🔴/⚪ (S-1), карточка — состояние, health, аптайм, рестарты, CPU/RAM от лимита, ревизия, время деплоя (S-2), «🩺 Запустить проверки» для всех или одного контейнера (S-3), «🔄 Обновить» (S-4).infra/deploy/remote.shставит на контейнер бота меткиtgit.shaиtgit.deployed_at.${{ … }}.Не сделано: S-5 «♻️ Перезапустить» (P2) — нужен runner (#13), прокси POST не пропускает.
Как проверено
httpx.MockTransport, GET-only как прокси; покрытие 91%, ruff, mypy strict.🤖 Generated with Claude Code