Files
infra/ansible/roles/lxc_docker_host
DmitryandClaude Opus 5 9725d3ea7c 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
2026-08-26 22:10:16 +03:00
..

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: dockerenabled: 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

- 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-стек стартовал на старом драйвере хранилища.