Files
obsidian-vault/family/documents/vault-sync/2026-09-02-hermes-taiga-crashloop.md
T

10 KiB
Raw Blame History

tags, created, updated, status
tags created updated status
truenas
hermes
taiga
crashloop
syncthing
vault-sync
incident
2026-09-02 2026-09-02 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 outuv run падает → restart: unless-stopped → без конца. hermes binary при этом даже не стартует (docker exec ... hermesexecutable file not found in $PATH — потому что venv в /tmp пуст/недоустановлен).

Почему uv качает на каждом старте + почему тайм-аутит

Проблема 1 — маршрут через мёртвый прокси. Активный compose /mnt/RED_2TB/docker/hermes/docker-compose.yml задаёт:

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 и телефон получил актуальное состояние:

ssh truenas_admin@mallexxx.duckdns.org "bash ~/sync-vault.sh"   # 3-phase (syncthing→vault→syncthing)

Проверка догона:

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 это учитывает).


Связанные заметки