lint / yamllint + ansible-lint + syntax-check (push) Canceled after 0s
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
132 lines
6.8 KiB
YAML
132 lines
6.8 KiB
YAML
---
|
||
# ============================================================================
|
||
# Дашборд-обзор всей инфраструктуры HomeLab (Homepage, gethomepage.dev).
|
||
#
|
||
# ОБЛАСТЬ ОТВЕТСТВЕННОСТИ
|
||
# Разворачивает compose-стек Homepage на LXC monitoring (рядом с Uptime
|
||
# Kuma) и ГЕНЕРИРУЕТ его конфиги из реестра homelab_services: одна плитка
|
||
# на сервис, ссылка на его UI, группировка по узлу Proxmox. Добавили
|
||
# сервис в реестр -> плитка появилась сама, второй список вести не нужно.
|
||
#
|
||
# Наружу дашборд НЕ публикуется: контейнер слушает только LAN-адрес CT 155,
|
||
# доступ из локальной сети или по OpenVPN. Внутренняя топология (IP, VMID,
|
||
# раскладка по нодам) на публичный периметр не выносится.
|
||
#
|
||
# ГРАНИЦА С reverse-proxy.yml
|
||
# Никакой общей области. Дашборд — отдельный стек на другом хосте, Caddyfile
|
||
# он не трогает.
|
||
#
|
||
# ЗАПУСК
|
||
# make dashboard (ansible-playbook playbooks/dashboard.yml)
|
||
# make dry-dashboard (--check --diff)
|
||
# Первый прогон, пока образ не закреплён по digest:
|
||
# ansible-playbook playbooks/dashboard.yml -e dashboard_allow_floating_tag=true
|
||
#
|
||
# СЕКРЕТЫ
|
||
# Виджет proxmox требует read-only токен homepage@pve!dashboard (роль
|
||
# PVEAuditor). Выпускается playbooks/bootstrap-dashboard-pve-token.yml,
|
||
# секрет кладётся в корневой .env как DASHBOARD_PVE_API_USER /
|
||
# DASHBOARD_PVE_API_TOKEN_ID / DASHBOARD_PVE_API_TOKEN_SECRET и подхватывается
|
||
# отсюда через lookup('env', ...). Без него дашборд работает — просто плитка
|
||
# "Proxmox кластер" показывает ошибку виджета, это не блокер.
|
||
#
|
||
# ТАРГЕТ
|
||
# По умолчанию homelab_dashboard_host (monitoring). Переопределяется ради
|
||
# blue-green: `-e dashboard_config_target=monitoring-new --limit monitoring-new`
|
||
# (голый --limit play не перенацеливает, а обнуляет — см. uptime-kuma.yml).
|
||
# ============================================================================
|
||
- name: Deploy the HomeLab infrastructure dashboard (Homepage) on the monitoring LXC
|
||
hosts: "{{ dashboard_config_target | default(homelab_dashboard_host | default('monitoring')) }}"
|
||
gather_facts: true
|
||
|
||
vars:
|
||
dash_root: "{{ homelab_dashboard_dir | default('/opt/homepage') }}"
|
||
dash_config_dir: "{{ (homelab_dashboard_dir | default('/opt/homepage')) ~ '/config' }}"
|
||
dash_bind: "{{ homelab_dashboard_bind_ip | default(expected_lan_ip) }}"
|
||
dash_port: "{{ homelab_dashboard_port | default(8082) }}"
|
||
dash_image: "{{ homelab_dashboard_image | default('') }}"
|
||
dash_allowed_hosts: >-
|
||
{{ homelab_dashboard_allowed_hosts | default(dash_bind ~ ':' ~ dash_port) }}
|
||
# Список узлов Proxmox, встречающихся в реестре, — по нему строятся группы.
|
||
dashboard_nodes: >-
|
||
{{ homelab_services | dict2items | map(attribute='value.node')
|
||
| unique | sort | list }}
|
||
# Секрет Proxmox-виджета из окружения (make load .env). Пусто -> плитка
|
||
# рендерится без данных. no_log на задаче, которая это пишет.
|
||
dash_pve_user: "{{ lookup('ansible.builtin.env', 'DASHBOARD_PVE_API_USER') }}"
|
||
dash_pve_token_id: "{{ lookup('ansible.builtin.env', 'DASHBOARD_PVE_API_TOKEN_ID') }}"
|
||
dash_pve_token_secret: "{{ lookup('ansible.builtin.env', 'DASHBOARD_PVE_API_TOKEN_SECRET') }}"
|
||
|
||
pre_tasks:
|
||
- name: Require the dashboard registry variables
|
||
ansible.builtin.assert:
|
||
that:
|
||
- dash_image | length > 0
|
||
- dash_bind | length > 0
|
||
fail_msg: >-
|
||
Не заданы homelab_dashboard_* в
|
||
inventory/group_vars/all/services.yml.
|
||
|
||
- name: Require the Homepage image to be pinned by digest
|
||
ansible.builtin.assert:
|
||
that:
|
||
- "'@sha256:' in dash_image or dashboard_allow_floating_tag | default(false) | bool"
|
||
fail_msg: >-
|
||
{{ dash_image }} не закреплён по digest. Выполни на
|
||
{{ inventory_hostname }}:
|
||
docker pull {{ dash_image }}
|
||
docker inspect --format '{{ '{{' }} index .RepoDigests 0 {{ '}}' }}' {{ dash_image }}
|
||
и пропиши tag@sha256 в homelab_dashboard_image. Разовый обход для
|
||
первого прогона: -e dashboard_allow_floating_tag=true
|
||
|
||
- name: Ensure the Homepage config directory exists
|
||
ansible.builtin.file:
|
||
path: "{{ dash_config_dir }}"
|
||
state: directory
|
||
owner: root
|
||
group: root
|
||
mode: "0755"
|
||
|
||
- name: Render Homepage configuration files from the registry
|
||
ansible.builtin.template:
|
||
src: "{{ item.src }}"
|
||
dest: "{{ dash_config_dir }}/{{ item.dest }}"
|
||
owner: root
|
||
group: root
|
||
mode: "0644"
|
||
loop:
|
||
- {src: homepage-settings.yaml.j2, dest: settings.yaml}
|
||
- {src: homepage-services.yaml.j2, dest: services.yaml}
|
||
- {src: homepage-widgets.yaml.j2, dest: widgets.yaml}
|
||
- {src: homepage-bookmarks.yaml.j2, dest: bookmarks.yaml}
|
||
loop_control:
|
||
label: "{{ item.dest }}"
|
||
register: dash_config_files
|
||
|
||
- name: Render the Homepage widget secrets file
|
||
ansible.builtin.template:
|
||
src: homepage.env.j2
|
||
dest: "{{ dash_root }}/homepage.env"
|
||
owner: root
|
||
group: root
|
||
mode: "0600"
|
||
register: dash_env_file
|
||
no_log: true
|
||
|
||
roles:
|
||
- role: compose_service
|
||
compose_service_name: homelab-homepage
|
||
compose_service_description: HomeLab infrastructure dashboard (Homepage)
|
||
compose_service_root: "{{ dash_root }}"
|
||
compose_service_root_mode: "0755"
|
||
compose_service_compose_file: docker-compose.yml
|
||
compose_service_compose_template: homepage-compose.yml.j2
|
||
# | bool обязателен: роль фильтрует триггеры по truthiness, а строка
|
||
# "False" из "{{ ... is changed }}" тоже истинна.
|
||
compose_service_restart_triggers:
|
||
- "{{ (dash_config_files is changed) | bool }}"
|
||
- "{{ (dash_env_file is changed) | bool }}"
|
||
compose_service_health_url: "http://{{ dash_bind }}:{{ dash_port }}/"
|
||
compose_service_health_status: [200]
|
||
compose_service_health_follow_redirects: none
|