Files
infra/docs/ai/architecture.md
T
DmitryandClaude Sonnet 5 05d8c748ab
lint / yamllint + ansible-lint + syntax-check (push) Canceled after 0s
feat: infrastructure dashboard (Homepage) generated from the service registry
playbooks/dashboard.yml deploys Homepage as a second compose stack on the
monitoring LXC (CT 155) next to Uptime Kuma and renders its config from
homelab_services: one tile per service, link to its UI, grouped by Proxmox
node. Adding a service to the registry is enough — no second service list.

- new registry consumer: playbooks/dashboard.yml + playbooks/templates/homepage-*.j2
- homelab_dashboard_* vars in group_vars/all/services.yml (top-level, like
  homelab_reverse_proxy_*); image pinned by digest, floating tag needs an
  explicit -e dashboard_allow_floating_tag=true
- bootstrap-dashboard-pve-token.yml: read-only homepage@pve!dashboard token
  (PVEAuditor) for the Proxmox widget, secret in the root .env as DASHBOARD_PVE_*
- Makefile: dashboard, dry-dashboard, bootstrap-dashboard-token
- container binds the LAN address only (192.168.1.30:8082), not published via Caddy
- docs: architecture.md Monitoring section, plan.md active task, consumer lists

Deployed to CT 155 on 2026-09-03: container healthy, http://192.168.1.30:8082/
returns 200, `make dashboard` idempotent, `make validate` and `make lint` green.
Pending operator steps: `make bootstrap-dashboard-token` (blocked in the agent
session as credential creation) and an Uptime Kuma status page with slug homelab.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KbuZrUoevfBgCpf5DCF4DG
2026-09-03 09:17:16 +03:00

8.6 KiB
Raw Blame History

Архитектура

Контекст и точки входа

Репозиторий является control plane, а не приложением с единым runtime. Оператор запускает цели ansible/Makefile; Make загружает локальные secrets, применяет safety gates и вызывает playbooks. ansible.cfg выбирает inventory, roles и локально установленные Galaxy collections.

Канонические источники:

  • хосты и группы: ansible/inventory/hosts.yml;
  • общий доступ и сеть: ansible/inventory/group_vars/all/main.yml;
  • сводные сведения о сервисах: ansible/inventory/group_vars/all/services.yml;
  • SSH transport: ansible/ssh_config;
  • ручные операции: ansible/Makefile.

Программные потребители реестра:

  • playbooks/reverse-proxy.yml — сборка Caddyfile;
  • playbooks/ru-vps-base.yml — стек Caddy и его закреплённый образ;
  • playbooks/pve-backup-jobs.yml — списки VMID заданий PBS (поле backup.job);
  • roles/backup_audit — VMID для аудита (флаг monitoring.backup_audit_vmid);
  • playbooks/validate.yml — сверка реестра с фактическим состоянием Proxmox;
  • playbooks/dashboard.ymlservices.yaml для Homepage-обзора инфраструктуры.

Остальное (pve-*.yml, status.yml, monitoring, SSH config) по-прежнему дублирует значения и должно меняться согласованно.

Топология

  • ru-vps: public VPS, qdevice, Caddy, OpenVPN server и SSH JumpHost.
  • cloud-pc, mini-pc: Proxmox VE nodes.
  • lxc_infra: PBS, OpenVPN gateway и service LXC.
  • monitoring: CT 146 на cloud-pc; Uptime Kuma активен, Prometheus stack заморожен.

Актуальные VMID, placement, IP, ports, domains и backup policy не копируются сюда: их нужно читать из homelab_services и сверять с hosts.yml.

Provisioning Flow

  1. make deploy-<service> загружает ignored .env из корня репозитория.
  2. playbooks/pve-<service>.yml создает или сверяет LXC.
  3. Часть playbooks вызывает roles/pve_lxc через Proxmox API.
  4. Остальные подключаются по SSH к PVE node и выполняют pct create/set/start.
  5. Следующий play настраивает LXC, runtime, systemd и health checks.

Два provisioner-пути имеют разные check-mode и ownership guards. Нельзя переносить service между ними как косметический рефакторинг.

Service Runtime

  • Большинство сервисов используют systemd units вокруг docker run.
  • Grimmory использует Compose и отдельный DOCKER-USER firewall unit.
  • Uptime Kuma и сохраненный monitoring stack используют legacy docker-compose.
  • lxc_docker_host и compose_service описывают будущий общий паттерн, но ни один production playbook их пока не вызывает.

Network Flow

ansible_ssh_common_args подключает ansible/ssh_config. Обычный путь управления:

controller -> ru-vps:3422 -> 192.168.1.x target

pbs и ovpn-mini являются direct-LAN исключениями. LXC обычно управляются как root, а PVE nodes и ru-vps - как service account ansible.

OpenVPN site tunnel:

ru-vps 10.78.0.1:8443/tcp <-> ovpn-mini 10.78.0.2 -> 192.168.1.0/24

Публичный service flow:

Internet -> Caddy on ru-vps -> OpenVPN -> ovpn-mini -> LAN service

Потеря ru-vps или site tunnel одновременно влияет на public upstreams и обычный SSH management path.

Reverse Proxy

playbooks/reverse-proxy.yml выбирает записи homelab_services с блоком proxy, валидирует metadata и Caddyfile, обновляет marked blocks и проверяет upstreams. Ansible управляет Caddyfile, но не установкой и lifecycle контейнера Caddy на ru-vps. Grimmory OPDS/KOReader routes имеют специальные headers и отключение compression; их нельзя упрощать без device compatibility tests.

Backup и Update

playbooks/pve-backup-jobs.yml задает cluster-level PBS schedules. Offsite restic profiles выполняются systemd timers и используют application-aware SQLite backup или MariaDB dump. roles/backup_audit проверяет freshness, restic check и выборочные restores, после чего атомарно пишет textfile metrics.

Update playbooks выполняют:

fresh backup/audit -> reapply service declaration -> health verification

Backup является prerequisite для ручного recovery, а не автоматическим rollback.

Monitoring

Uptime Kuma в CT 146 является активным monitoring UI. Его роль останавливает и отключает homelab-monitoring, сохраняя конфигурацию и данные Prometheus stack. make monitoring защищен CONFIRM=1 и предназначен только для отдельно принятого решения о восстановлении старого stack.

Exporter roles, groups и backup metrics остаются в репозитории. Hardcoded Prometheus targets могут расходиться с inventory, пока stack заморожен.

playbooks/dashboard.yml (make dashboard) поднимает Homepage вторым compose-стеком на том же LXC monitoring: обзорная стартовая страница со списком всех сервисов, ссылками на их UI и виджетами Proxmox/Uptime Kuma. services.yaml, settings.yaml, widgets.yaml, bookmarks.yaml рендерятся из homelab_services шаблонами playbooks/templates/homepage-*.j2 — отдельный список сервисов не ведётся. Контейнер слушает только LAN-адрес CT 155 (homelab_dashboard_bind_ip), наружу через Caddy не публикуется. Виджет Proxmox использует read-only токен homepage@pve!dashboard (роль PVEAuditor, make bootstrap-dashboard-token), секрет — в корневом .env как DASHBOARD_PVE_*. Образ Homepage закрепляется по digest как остальные active images; до первого закрепления плейбук падает на assert'е (обход — -e dashboard_allow_floating_tag=true).

Grimmory MCP

tools/grimmory-mcp/src/server.js запускает локальный stdio MCP. Grimmory API используется read-only; authentication POST не меняет library data. Явно вызванные sync tools читают API, опционально загружают cover, атомарно обновляют managed sections Obsidian notes и запускают внешний vault index script.

Sync не является общей транзакцией: full sync может закончиться после частичного набора успешных book updates. Vault path и credential file защищены отдельными проверками, описанными в edge-cases.md.

Testing Boundaries

  • Ansible имеет static lint и syntax checks, но не имеет Molecule/idempotence harness.
  • check.yml проверяет reachability и expected IP, а не service health.
  • status.yml формирует наблюдательный отчет и не является failing health gate.
  • Grimmory MCP имеет Node test suite.
  • Gitea Actions workflow существует, но runner и Actions не активированы.

Неизвестно

  • Текущие runtime versions Proxmox VE, OpenVPN, Caddy и restic не закреплены repo manifests.
  • UI-only состояние AdGuard, Uptime Kuma monitors и часть service credentials не может быть установлена из репозитория.
  • Наличие DHCP reservation для Grimmory и намеренность отсутствия backup CT 148 требуют проверки оператором.