From 7700ed5a8819af18d2763ce9d8ad9e9f0efb5c23 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Wed, 26 Aug 2026 22:10:38 +0300 Subject: [PATCH] Sync documentation with the actual infrastructure The host table listed 9 hosts against 16 in the inventory, the role tree did not match roles/, and the documented setup path used a venv that no longer works. Describe the current entry points instead: nix develop, make, and the ssh_config include that makes `ssh gitea` work by hand. Point at `make docs` as the way to regenerate the host table rather than editing it, since that is what drifted. Also record what is deliberately incomplete: lxc_docker_host and compose_service exist but are not wired into any playbook, and LXC creation is still split between direct pct create over SSH and the pve_lxc API role. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01GTocXkGUUazHdKKd3r9k71 --- AGENTS.md | 222 +++++++++++++++++++++++++++++++++++------------------- README.md | 64 +++++++++++----- 2 files changed, 189 insertions(+), 97 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 864f8c6..075cd35 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -34,113 +34,178 @@ When introducing infra changes, update the relevant Obsidian note to keep docume ## Quick Start +Окружение собрано в Nix — venv и системные пакеты не нужны. + ```bash -cd ansible +nix develop # или один раз: direnv allow -# Setup (once) -python3 -m venv .venv -. .venv/bin/activate -pip install -r requirements.txt -ansible-galaxy collection install -r requirements.yml -p collections - -# Basic connectivity check -ansible-playbook playbooks/check.yml - -# Privileged tasks -ansible-playbook playbooks/.yml -K - -# Proxmox API tasks (from .env) -cp .env.example .env -# Edit .env with real values -. ./.env -ansible-playbook playbooks/pve-*.yml +# Один раз на клон: galaxy-коллекции +ansible-galaxy collection install -r ansible/requirements.yml -p ansible/collections ``` +Дальше всё управление идёт через `make` из каталога `ansible/`: + +```bash +cd ansible +make help # список всех целей — начинать отсюда +make check # связность и ожидаемые IP +make status # сводное состояние всей инфраструктуры (read-only) +make lint # ansible-lint + yamllint +make docs # актуальная таблица хостов из inventory + +make deploy-gitea # playbooks/pve-gitea.yml, .env подхватывается сам +make dry-gitea # то же в режиме --check --diff +make update-gitea # бэкап -> обновление -> health-check +``` + +`make` без аргументов печатает `help`. Опасные цели (`mihomo-harden`, `monitoring`, +`update-all`) требуют явного `CONFIRM=1`. Дополнительные флаги — через `EXTRA`: + +```bash +make status EXTRA="--limit '!gyro'" +``` + +`gyro` использует шифрованный `host_vars/gyro/vault.yml`, поэтому для него нужен +`--ask-vault-pass` (цель `make gyro` добавляет флаг сама). + +### SSH руками + +Транспорт описан в `ansible/ssh_config` — один источник правды и для Ansible, +и для терминала. Чтобы заработал `ssh gitea`, добавь в `~/.ssh/config`: + +``` +Include /home/ada/Documents/Projects/HomeLab/infras/ansible/ssh_config +``` + +SSH берёт первое совпадение: Include в начале файла — побеждают настройки репозитория, +в конце — личные записи из `~/.ssh/config.d/`. На Ansible порядок не влияет, он ходит +с явным `-F`. + ## Active Infrastructure +Каноничный источник — `ansible/inventory/hosts.yml` и реестр сервисов +`ansible/inventory/group_vars/all/services.yml`. Актуальную таблицу всегда можно +получить командой `make docs`, поэтому здесь — только опорная картина. + ### Nodes | Name | Role | LAN IP | Notes | |---|---|---:|---| -| `ru-vps` | Public VPS, JumpHost, qdevice, OpenVPN server | `157.22.231.198:3422` | OpenVPN `10.78.0.1` | -| `cloud-pc` | Proxmox VE node, PBS LXC, storage | `192.168.1.5` | Main node | +| `ru-vps` | Public VPS, JumpHost, qdevice, OpenVPN server, Caddy | `157.22.231.198:3422` | OpenVPN `10.78.0.1` | +| `cloud-pc` | Proxmox VE node, storage | `192.168.1.5` | Main node | | `mini-pc` | Proxmox VE node | `192.168.1.10` | Secondary node | -| `pbs` | Proxmox Backup Server LXC | `192.168.1.20` | On cloud-pc | -| `ovpn-mini` | OpenVPN gateway LXC | `192.168.1.23` | OpenVPN `10.78.0.2` | -| `vaultwarden` | Vaultwarden LXC | `192.168.1.24` | | -| `gitea` | Gitea LXC | `192.168.1.25` | | -| `memoir-bot` | Telegram memoir bot LXC | `192.168.1.26` | | -| `mihomo` | Local proxy/UI LXC | `192.168.1.27` | UI `:8080`, API `:9090` | +| `pbs` | Proxmox Backup Server LXC (CT 120) | `192.168.1.20` | Прямой доступ, без ProxyJump | +| `ovpn-mini` | OpenVPN gateway LXC (CT 132) | `192.168.1.23` | OpenVPN `10.78.0.2`, без ProxyJump | +| `vaultwarden` | Vaultwarden LXC (CT 140) | `192.168.1.24` | `pass.ada-dev.ru` | +| `gitea` | Gitea LXC (CT 141) | `192.168.1.25` | `git.ada-dev.ru`, SSH `:2222` | +| `memoir-bot` | Telegram memoir bot LXC (CT 142) | `192.168.1.26` | образ собирается локально | +| `mihomo` | Local proxy/UI LXC (CT 143) | `192.168.1.27` | UI `:8080`, API `:9090`, proxy `:7890/:7891` | +| `adguard` | AdGuard Home LXC (CT 144) | `192.168.1.28` | DNS `:53`, UI `:3000` | +| `docker-test` | Песочница/кандидат в CI-раннеры (CT 145) | `192.168.1.29` | | +| `monitoring` | Monitoring LXC (CT 146) | `192.168.1.30` | Uptime Kuma активен, Prometheus заморожен | +| `hermes-ai` | AI-хост (CT 147) | `192.168.1.31` | ходит наружу через mihomo | +| `emergency-bot` | Telegram-бот break-glass доступа (CT 148) | `192.168.1.32` | | +| `grimmory` | Grimmory + MariaDB (CT 149) | `192.168.1.34` | `books.ada-dev.ru` | +| `gyro` | Investment allocator (CT 150) | `192.168.1.35` | vault-переменные, outbound-only | ### Inventory Groups - `homelab` — ru-vps - `pve_nodes` — cloud-pc, mini-pc -- `lxc_infra` — pbs, ovpn-mini, vaultwarden, gitea, memoir-bot, mihomo +- `lxc_infra` — все LXC (13 шт.) +- `monitoring_server` — monitoring +- `monitoring_exporters` — хосты с Node Exporter +- `monitoring_smart_exporters` — cloud-pc, mini-pc - `vpn_openvpn` — ru-vps, ovpn-mini -- `shell_hosts` — ru-vps, cloud-pc, mini-pc -- `servers` — all managed hosts +- `shell_hosts` — ru-vps, cloud-pc, mini-pc, hermes-ai +- `servers` — все управляемые хосты + +Общие переменные живут в `inventory/group_vars/`, а не в `hosts.yml`: +`group_vars/all/main.yml` (сеть, доступ, OpenVPN), `group_vars/lxc_infra/main.yml` +(LXC ходят под root без sudo), `group_vars/all/services.yml` (реестр сервисов). ### Transport -- **OpenVPN**: ru-vps (10.78.0.1) ↔ ovpn-mini (10.78.0.2), port 8443/tcp -- **JumpHost**: SSH to cloud-pc/mini-pc via ProxyJump ru-vps +- **OpenVPN**: ru-vps (10.78.0.1) ↔ ovpn-mini (10.78.0.2), порт 8443/tcp +- **JumpHost**: SSH к нодам и LXC через ProxyJump `ru-vps`; исключения — `pbs` и + `ovpn-mini`, они доступны напрямую по LAN +- Всё это описано в `ansible/ssh_config`; Ansible подключает его через + `ansible_ssh_common_args` в `group_vars/all/main.yml` (путь считается от + `inventory_dir`, поэтому не зависит от cwd и места клона) ## Directory Structure ``` -ansible/ -├── ansible.cfg # Ansible configuration -├── inventory/ -│ └── hosts.yml # Canonical host list and variables -├── playbooks/ # Entry points -│ ├── check.yml # Connectivity check -│ ├── pve-*.yml # Proxmox API tasks (need .env) -│ ├── openvpn-*.yml # OpenVPN transport setup -│ └── *.yml # Other tasks -├── roles/ # Reusable units -│ ├── backup_audit/ # PBS/restic backup audit -│ ├── bash_config/ # Unified bash config -│ ├── base/ # Base packages/config -│ ├── docker/ # Docker setup -│ ├── openvpn_gateway/ # OpenVPN client gateway -│ ├── pve_lxc/ # Proxmox LXC creation -│ └── ufw/ # Firewall rules -├── tasks/ # Task snippets -└── requirements.txt/yml # Dependencies +flake.nix / .envrc # Nix dev-окружение (ansible, линтеры, python-зависимости) +.ansible-lint / .yamllint # Конфигурация линтеров +.gitea/workflows/lint.yml # CI: yamllint + ansible-lint + syntax-check -archive/2026-07-proxmox-migration/ # Historical configs (reference only) +ansible/ +├── Makefile # ЕДИНАЯ точка входа для ручного управления (make help) +├── ansible.cfg +├── ssh_config # Транспорт: ProxyJump, пользователи, ключи +├── scripts/ +│ └── gen-inventory-docs.py +├── inventory/ +│ ├── hosts.yml # Только адреса и индивидуальные факты хостов +│ ├── group_vars/ +│ │ ├── all/main.yml # Общие переменные +│ │ ├── all/services.yml # Реестр сервисов homelab_services +│ │ └── lxc_infra/main.yml +│ └── host_vars/gyro/ # main.yml + шифрованный vault.yml +├── playbooks/ +│ ├── check.yml # Связность и ожидаемые IP +│ ├── status.yml # Read-only сводка по всей инфраструктуре +│ ├── reverse-proxy.yml # Единый Caddy-плейбук по реестру сервисов +│ ├── pve-*.yml # Создание LXC (нужен .env) +│ ├── *-update.yml # Обновления: бэкап -> апдейт -> health-check +│ └── openvpn-*.yml +├── roles/ +│ ├── lxc_docker_host/ # LXC под Docker: пакеты, fuse-overlayfs, ufw +│ ├── compose_service/ # compose.yml + systemd-юнит + health-check +│ ├── pve_lxc/ # Создание LXC через Proxmox API +│ ├── backup_audit/ # Аудит PBS и restic +│ ├── monitoring_*/ # Prometheus-стек (заморожен), экспортеры +│ ├── uptime_kuma/ # Активный мониторинг +│ ├── emergency_access/ # Break-glass reverse SSH +│ ├── emergency_bot/ # Telegram-бот break-glass +│ ├── gyro/ # Investment allocator +│ ├── openvpn_gateway/ # OpenVPN транспорт +│ └── bash_config/ # Единый bash-конфиг +└── tasks/ + +archive/2026-07-proxmox-migration/ # Историческое, только как справка ``` +Роли `lxc_docker_host` и `compose_service` созданы, но пока не подключены ни к одному +плейбуку — миграция `pve-*.yml` на них не выполнена. Пример использования и перечень +того, что меняется на живом хосте при переходе, — в `roles/compose_service/README.md`. + ## Common Playbooks +Предпочитай `make` — он сам грузит `.env` и защищает опасные цели. + ```bash -# Check connectivity and expected IPs -ansible-playbook playbooks/check.yml - -# Bootstrap Proxmox API token from mini-pc (requires sudo) -ansible-playbook playbooks/bootstrap-pve-api-token.yml -K - -# OpenVPN transport setup (requires privilege) -ansible-playbook playbooks/openvpn-vps-mini.yml -K -ansible-playbook playbooks/openvpn-check.yml - -# Unified bash config for shell hosts -ansible-playbook playbooks/bash-config.yml - -# Install user's SSH public key on all managed hosts -ansible-playbook playbooks/user-ssh-key.yml - -# Backup audit (PBS + restic offsite) -ansible-playbook playbooks/backup-audit.yml +make check # связность и ожидаемые IP +make status # read-only сводка: хосты, юниты, диски, VPN, бэкапы +make deploy- # playbooks/pve-.yml +make dry- # то же с --check --diff +make update- # gitea | vaultwarden | adguard | mihomo | grimmory +make reverse-proxy # Caddy на ru-vps по реестру сервисов +make backup-audit # аудит PBS + offsite restic +make openvpn-check # проверка транспорта ru-vps <-> ovpn-mini +make bash-config # единый bash-конфиг на shell_hosts +make user-ssh-key # разложить публичный ключ на все хосты ``` +Обновления всегда идут в порядке: свежий бэкап/аудит -> обновление -> health-check. +Образы закреплены по `tag@sha256:digest`; floating-теги и авто-апдейтеры не используются. ## Proxmox API Tasks -Proxmox playbooks require environment variables: +Плейбукам `pve-*.yml` нужны переменные Proxmox API. Держи их в `ansible/.env` +(файл в `.gitignore`, шаблон — `.env.example`): ```bash -# From .env file PROXMOX_HOST= PROXMOX_USER= PROXMOX_TOKEN_ID= @@ -148,19 +213,20 @@ PROXMOX_TOKEN_SECRET= PROXMOX_VALIDATE_CERTS=false ``` -Usage: +`make` подхватывает `.env` сам и падает с внятным сообщением, если его нет — +руками `. ./.env` делать не нужно: ```bash -. ./.env -ansible-playbook playbooks/pve-ovpn-mini.yml -ansible-playbook playbooks/pve-vaultwarden.yml -ansible-playbook playbooks/pve-gitea.yml +make env-check # проверить, что .env на месте и заполнен +make dry-gitea # сначала всегда --check --diff +make deploy-gitea ``` -Or bootstrap token directly from node: +Выпустить токен, если его ещё нет: ```bash -ansible-playbook playbooks/bootstrap-pve-api-token.yml -K +make bootstrap-pve-token # прямо с ноды, нужен sudo +make bootstrap-monitoring-token # отдельный read-only токен для мониторинга ``` ## Secrets Policy diff --git a/README.md b/README.md index 7f26d94..a4bbbd7 100644 --- a/README.md +++ b/README.md @@ -1,34 +1,60 @@ # HomeLab Infrastructure -Active HomeLab infrastructure is managed through Ansible. +Активная инфраструктура домашней лаборатории управляется через Ansible. +Каноничные инструкции для людей и агентов — в [AGENTS.md](./AGENTS.md). -## Active Files +## Быстрый старт -- `ansible/` — current control plane. -- `ansible/inventory/hosts.yml` — inventory and host facts. -- `ansible/playbooks/check.yml` — safe connectivity/facts check. +Окружение собрано в Nix, venv не нужен: -## Archive +```bash +nix develop # или один раз: direnv allow -Historical pre-Proxmox material is kept under: - -```text -archive/2026-07-proxmox-migration/ +# Один раз на клон +ansible-galaxy collection install -r ansible/requirements.yml -p ansible/collections ``` -It contains old NixOS configs, Docker Compose service definitions, Gitea workflows, deploy scripts and old Ansible bootstrap playbooks. - -## Basic Check +Всё управление — через `make` из `ansible/`: ```bash cd ansible -ansible-playbook playbooks/check.yml +make help # список целей, начинать отсюда +make check # связность и ожидаемые IP +make status # read-only сводка по всей инфраструктуре +make lint # ansible-lint + yamllint ``` +Деплой и обновления: + +```bash +make dry-gitea # предпросмотр (--check --diff) +make deploy-gitea # применить +make update-gitea # бэкап -> обновление -> health-check +``` + +`.env` с Proxmox-токенами подхватывается автоматически. Опасные цели требуют `CONFIRM=1`. + +## SSH руками + +`ansible/ssh_config` — единый источник правды по SSH и для Ansible, и для терминала. +Добавь в `~/.ssh/config`, чтобы заработал `ssh gitea`: + +``` +Include /home/ada/Documents/Projects/HomeLab/infras/ansible/ssh_config +``` + +## Структура + +- `ansible/` — control plane: `Makefile`, `inventory/`, `playbooks/`, `roles/`, `ssh_config` +- `ansible/inventory/group_vars/all/services.yml` — реестр сервисов (VMID, IP, порты, домены, образы) +- `flake.nix` — dev-окружение +- `.gitea/workflows/lint.yml` — CI: yamllint, ansible-lint, syntax-check +- `archive/2026-07-proxmox-migration/` — исторические NixOS/Docker конфиги, только как справка + ## Grimmory MCP -`tools/grimmory-mcp/` contains the read-only Grimmory API integration for -OpenCode and the explicitly invoked Obsidian synchronization tools. +`tools/grimmory-mcp/` содержит read-only интеграцию с Grimmory API для OpenCode +и явно вызываемые инструменты синхронизации с Obsidian. ```bash npm install --prefix tools/grimmory-mcp @@ -36,6 +62,6 @@ npm run configure --prefix tools/grimmory-mcp npm test --prefix tools/grimmory-mcp ``` -OpenCode registers the server globally. After restarting OpenCode, use -`/grimmory-sync` to update individual book notes under `90 Library/Books` and -covers under `99 System/Export/Grimmory/Covers`. +OpenCode регистрирует сервер глобально. После перезапуска OpenCode используй +`/grimmory-sync` для обновления заметок книг в `90 Library/Books` и обложек +в `99 System/Export/Grimmory/Covers`.