--- tags: [truenas, hermes, taiga, crashloop, syncthing, vault-sync, incident] created: 2026-09-02 updated: 2026-09-02 status: open — root cause identified, fix NOT yet applied (ждёт Alex) --- # Incident 2026-09-02: hermes-taiga crash-loop (16 339 рестартов) — Taiga git-sync стоит с авг, телефон видит устаревший vault **Родительские контексты:** [[2026-08-31-syncthing-truenas-incident]], [[2026-09-02-restore-privilege-scope]]. Здесь документируем свежую поломку: контейнер `hermes-taiga` упал в бесконечный restart-loop, из-за чего 3-phase Taiga git-sync **не выполняется**, и обе Taiga-копии vault (`/vault` и `/obsidian-syncthing`) отстали от bare repo **на месяц**. **Симптом (жалоба Alex, «syncthing state не совпадает с маком/гитом»):** состояние папки Syncthing для телефона не совпадает с Mac / с тем, что запушено в git. --- ## Диагноз по цепочке (проверено 2026-09-02) | Сторона | Состояние | HEAD | |---|---|---| | Mac `~/obsidian` | ✅ синхронен с bare repo (ahead=0/behind=0) | `2fab879` (2026-09-02) | | Bare repo `obsidian-vault.git` (истина) | ✅ источник | `2fab879` (2026-09-02) | | TrueNAS Syncthing P2P → телефон | ✅ работает (folder `k5vyy-gzdgj` «Obsidian Vault», up 2 days healthy) | — | | **Taiga `/storage/obsidian-syncthing`** | ⛔ **отстал на месяц** | `ceea848` (2026-08-01) | | **Taiga `/storage/obsidian`** | ⛔ **отстал на месяц** | `ceea848` (2026-08-01) | **Корень (проверено):** контейнер `hermes-taiga` в **crash-loop — `Restarts=16339`**, `StartedAt` постоянно сбрасывается. Логи: на каждом старте `uv` пытается докачать зависимости `pytz`, `markdown-it-py` с PyPI → **`client error (Connect) / operation timed out`** → `uv run` падает → `restart: unless-stopped` → без конца. `hermes` binary при этом даже не стартует (`docker exec ... hermes` → `executable file not found in $PATH` — потому что venv в /tmp пуст/недоустановлен). ### Почему `uv` качает на каждом старте + почему тайм-аутит **Проблема 1 — маршрут через мёртвый прокси.** Активный compose `/mnt/RED_2TB/docker/hermes/docker-compose.yml` задаёт: ```yaml environment: - HTTP_PROXY=socks5://vless-proxy:1080 - HTTPS_PROXY=socks5://vless-proxy:1080 - UV_CACHE_DIR=/tmp/uv-cache - NO_PROXY=portainer-mcp,homeassistant,localhost,127.0.0.1 ``` Весь исходящий HTTP (вкл. PyPI для `uv`) идёт через `socks5://vless-proxy:1080`. А **outbound `vless-proxy` мёртв** (см. `truenas-infrastructure.md` шапка: `v.qentra.top` удалён, DNS остался в Cloudflare → трафик из прокси наружу не выходит). ⇒ `uv` не может скачать депы → timeout. **Проблема 2 — `UV_CACHE_DIR=/tmp/uv-cache`, а не впекённый venv.** Образ `hermes-taiga:latest` собран 2026-08-24 (`FROM node:20-slim`, entrypoint `["uv","run","hermes","gateway","run"]`, в Dockerfile при build идёт `uv pip install -e ".[all]"`). Но compose перенаправляет uv-кэш в `/tmp/uv-cache` (tmpfs контейнера), который **обнуляется на каждый рестарт** → при каждом старте `uv run` пере-синхронизирует депы → опять PyPI → опять timeout. Порочный круг. (Вместе с тем контейнер смонтирован с настоящей конфигой в `config/`, а деps НЕ должен перекачивать при здоровом образе/запуске.) ### Контейнер hermes-taiga (для справки) - Image: `hermes-taiga:latest`, `container_name: hermes-taiga`, `restart: unless-stopped` - Entrypoint (в образе): `["uv","run","hermes","gateway","run"]` - WorkingDir: `/opt/hermes` - Mounts (compose активный): - `/mnt/RED_2TB/storage/obsidian-syncthing -> /obsidian-syncthing:rw` (полная копия, phone) - `/mnt/RED_2TB/storage/obsidian -> /vault:rw` (sparse) - `/mnt/RED_2TB/storage/git/obsidian-vault.git -> /vault.git` - `/mnt/RED_2TB/docker/hermes/config -> /opt/data` - Env: `HERMES_ALLOW_ROOT_GATEWAY=1`, `UV_CACHE_DIR=/tmp/uv-cache`, `HTTP_PROXY/HTTPS_PROXY=socks5://vless-proxy:1080`, `NO_PROXY=...`; `env_file: .env` - Сети: `taiga_net` (внутр) + `ha_net`(external `ha_default`); `depends_on: portainer-mcp (healthy)` > В `/mnt/RED_2TB/docker/hermes/` есть **второй, Новый Dockerfile** в `build/Dockerfile` (debian:13, multi-stage uv/gosu, `COPY .`, `uv pip install --no-cache-dir -e ".[all]"`, `chmod a+rX`, свой `/entrypoint.sh`, `HERMES_WEB_DIST`), а в корне — **Старый активный Dockerfile** (`node:20-slim`, клонирует upstream, entrypoint `uv run`). Активный compose ссылается на старый (`context: ., dockerfile: Dockerfile`). Это наследие расхождения build/каноне — кандидат на консолидацию, но осторожно. ### Почему это ломает vault-sync Taiga 3-phase sync (`~/sync-vault.sh`, Hermes cron) запускается **внутри агента hermes-taiga**. Раз агент в crash-loop и `hermes` не стартует → cron не выполняется → **оба Taiga-клиента не тянут из bare repo с ~2026-08-01**. Телефон (Syncthing-копия `obsidian-syncthing`) продолжает синкаться P2P с тем, что там застряло (старое), а git-история Mac/bare repo ушла вперёд → рассинхрон, который видит Alex. **⚠️ Ситуация с `file:///vault.git` / bare repo:** bare repo в порядке (2fab879). Просто Taiga-клиенты не делают fetch/merge с августа. Это НЕ поломка прав (та уже решена 2026-09-02), а именно мёртвый агент. --- ## ЧТО ЕЩЁ НЕ ДЕЛАЛОСЬ (остаток — конец сессии) Диагностика остановилась на идентификации корня. **Фикс НЕ применён** (read-only проверка venv/прокси не прошла — подтверждение Alex истекло). Не сделано: 1. Проверка полноты `.venv` в образе `hermes-taiga:latest` (throwaway-контейнер read-only): есть ли `pytz`/`markdown-it-py`/`hermes_cli`. 2. Проверка живости `vless-proxy` изнутри (fetch через socks5). 3. Выбор и применение фикса (см. ниже). --- ## Варианты фикса (к обсуждению, НЕ внедрено) **Ключевая развилка — связь Taiga с внешним миром.** Taiga (в отличие от Kraken) **нужна сеть наружу** (web, Telegram через API). Раз `vless-proxy` мёртв, вопрос: восстановить прокси-выход или дать Taiga прямой egress. На TrueNAS есть рабочий Xray-сервер на `vpn.mallexxx.duckdns.org:443` (`xray-admin`, client `user1` direct) — можно нацелить прокси Taiga на него. Подробно прокси-инфра: `family/how-to/truenas-infrastructure.md`. Непосредственно краш-луп чинить, чтобы агент поднялся: - **Убрать зависимость startup от PyPI:** сборка образа должна впекять полный venv и не делать `uv run`-reinstall на старте (перейти на улучшенный `build/Dockerfile` с `/entrypoint.sh`), И/ИЛИ убрать `/tmp/uv-cache` в пользу персистентного кэша на `config/` (bind mount `/opt/data`). - **Восстановить прокси:** обновить outbound `vless-proxy` на рабочий endpoint (`vpn.mallexxx.duckdns.org`, user1) или убрать `HTTP(S)_PROXY` если прокси не обязателен для Taiga (тогда `uv` сходит на PyPI напрямую с TrueNAS). После подъёма агента — **ручной прогон 3-phase sync** чтоб Taiga-копии догнать до bare repo и телефон получил актуальное состояние: ```bash ssh truenas_admin@mallexxx.duckdns.org "bash ~/sync-vault.sh" # 3-phase (syncthing→vault→syncthing) ``` Проверка догона: ```bash ssh truenas_admin@mallexxx.duckdns.org 'for d in /mnt/RED_2TB/storage/obsidian /mnt/RED_2TB/storage/obsidian-syncthing; do echo "== $d"; git -C "$d" rev-list --left-right --count main...origin/main; git -C "$d" log -1 --format="%h %ci %s"; done' ``` > ⚠️ В `obsidian-syncthing` есть **живые телефонные незакоммиченные изменения** (`.stversions/...`, `altai-build-checklist.md` и др.) — при ручном мерже вручную не затереть входящее с телефона (штатный 3-way merge в sync-vault-lib это учитывает). --- ## Связанные заметки - [[truenas-infrastructure]] — шапка: vless-proxy outbound мёртв; Hermes-Taiga раздел - [[vault-git-sync]] / [[obsidian-sync]] — архитектура sync и его сценарии - [[syncthing-truenas-android]] — syncthing-копия и её mount - [[2026-08-31-syncthing-truenas-incident]] — родитель: поломка прав syncthing-папки (другая, решена) - [[2026-09-02-restore-privilege-scope]] — родитель: поломка прав после restore (решена)