Add service registry, shared roles and unified reverse proxy

Collect the facts about all 14 services -- VMID, node, address, ports,
domain, pinned images, resources, backup and monitoring participation --
into group_vars/all/services.yml. Values are taken from the existing
playbooks; gaps are marked null rather than invented.

Replace reverse-proxy-{gitea,vaultwarden,grimmory}.yml with a single
playbook iterating over registry entries that declare a domain. It keeps
every check the three had, preserves grimmory's richer Caddy block
byte-for-byte, and restarts Caddy once when any site changed instead of
up to three times. Verified with --check --diff against ru-vps: ok=6
changed=0, so it reproduces the current Caddyfile exactly.

Add two roles factoring out the skeleton duplicated across the pve-*
playbooks: lxc_docker_host (packages, /dev/fuse assertion, fuse-overlayfs
storage driver, UFW baseline) and compose_service (compose file, systemd
unit, config validation, health check). They are not wired into any
playbook yet -- migrating a live service is a separate, per-service step;
compose_service/README.md shows the Gitea example and spells out what
actually changes on the host.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GTocXkGUUazHdKKd3r9k71
This commit is contained in:
Dmitry
2026-08-26 22:10:16 +03:00
co-authored by Claude Opus 5
parent ec3b736250
commit 9725d3ea7c
15 changed files with 1503 additions and 218 deletions
+83
View File
@@ -0,0 +1,83 @@
# lxc_docker_host
Приводит непривилегированный Proxmox LXC в состояние «здесь можно запускать
Docker»: пакеты, проверка `/dev/fuse`, `storage-driver: fuse-overlayfs`,
запуск демона и базовый UFW.
Роль вынесена из повторяющихся блоков `playbooks/pve-*.yml`
(gitea, vaultwarden, mihomo, adguard, memoir-bot, docker-test, grimmory,
hermes-ai) — суммарно около 350 строк копипасты.
## Что делает
1. Ставит `ca-certificates`, `curl`, `docker.io`, `fuse-overlayfs`
(+ `lxc_docker_host_extra_packages`, `ufw` при управлении фаерволом).
2. `stat` + `assert` на `/dev/fuse`: без символьного устройства
fuse-overlayfs не работает, и Docker молча деградирует до `vfs`.
Сообщение об ошибке подсказывает, какие строки добавить в
`/etc/pve/lxc/<vmid>.conf` на узле PVE.
3. Пишет `/etc/docker/daemon.json` со `storage-driver: fuse-overlayfs`.
4. `systemd: docker``enabled: true`, `restarted` при смене daemon.json,
иначе `started`.
5. UFW: SSH из `homelab_lan_cidr` и `openvpn_network_cidr`, node-exporter
9100/tcp с хоста мониторинга (192.168.1.30), произвольные порты сервиса
из `lxc_docker_host_ufw_service_rules`, затем `policy deny incoming`.
Разрешающие правила ставятся ДО включения политики — иначе прогон
обрывает собственную SSH-сессию.
6. Проверяет `docker info --format '{{.Driver}}'` и падает при расхождении.
## Переменные
Полный список с комментариями — в `defaults/main.yml`. Ключевые:
| Переменная | По умолчанию | Назначение |
|---|---|---|
| `lxc_docker_host_extra_packages` | `[]` | доп. пакеты сервиса |
| `lxc_docker_host_require_fuse` | `true` | проверять `/dev/fuse` |
| `lxc_docker_host_storage_driver` | `fuse-overlayfs` | драйвер хранилища |
| `lxc_docker_host_manage_ufw` | `true` | трогать ли UFW вообще |
| `lxc_docker_host_ssh_sources` | LAN + OpenVPN | откуда разрешён SSH |
| `lxc_docker_host_allow_node_exporter` | `true` | 9100 с хоста мониторинга |
| `lxc_docker_host_ufw_service_rules` | `[]` | порты сервиса |
| `lxc_docker_host_ufw_enable` | `true` | включать `deny incoming` |
| `lxc_docker_host_verify_storage_driver` | `true` | финальная проверка |
## Пример: как выглядела бы подготовка хоста Grimmory
```yaml
- name: Prepare the Grimmory Docker host
hosts: grimmory
gather_facts: true
vars:
ansible_become: false
roles:
- role: lxc_docker_host
lxc_docker_host_extra_packages:
- mariadb-client
- openssl
lxc_docker_host_install_node_exporter: true
lxc_docker_host_ufw_service_rules:
- port: "{{ homelab_services.grimmory.ports[0].port }}"
proto: tcp
comment: Grimmory HTTP
sources:
- "{{ homelab_lan_cidr }}"
- "{{ openvpn_network_cidr }}"
```
Эти 12 строк заменяют 86 строк из `playbooks/pve-grimmory.yml`.
## Чего роль НЕ делает
* Не создаёт LXC и не правит `/etc/pve/lxc/<vmid>.conf` — это роль `pve_lxc`
и соответствующий `pve-*.yml`. Роль только проверяет результат.
* Не публикует порты Docker в обход UFW. Помните: `-p` в Docker обходит UFW,
поэтому для публикуемых портов нужны правила в цепочке `DOCKER-USER`
(см. `grimmory-docker-firewall` в `playbooks/pve-grimmory.yml`).
* Не ставит node-exporter по умолчанию — этим занимается `monitoring_exporter`.
## Handlers
Их нет намеренно. Docker перезапускается прямо в задаче через
`state: restarted if changed else started`: handler отработал бы в конце
play, уже после того как compose-стек стартовал на старом драйвере хранилища.