Dashboard: add server start dashboard via homepage
This commit is contained in:
@@ -64,7 +64,8 @@ uv run ansible-galaxy install --role-file requirements.yml
|
||||
- `playbook-wakapi.yml` — трекинг времени.
|
||||
- `playbook-memos.yml` — заметки.
|
||||
- `playbook-outline.yml` — вики/база знаний.
|
||||
- `playbook-homepage.yml` — дашборд (образ из Yandex Registry).
|
||||
- `playbook-homepage.yml` — кастомная домашняя страничка на apex `vakhrushev.me` (образ из Yandex Registry).
|
||||
- `playbook-dashboard.yml` — дашборд со списком сервисов (gethomepage.dev) на `start.vakhrushev.me`, закрыт за Authelia.
|
||||
- `playbook-rssbridge.yml` — RSS-агрегатор.
|
||||
- `playbook-netdata.yml` — мониторинг.
|
||||
- `playbook-dozzle.yml` — просмотр Docker-логов.
|
||||
@@ -99,6 +100,7 @@ uv run ansible-galaxy install --role-file requirements.yml
|
||||
- Большинство приложений определяют переменные inline в плейбуке. Отдельные файлы переменных только у homepage и transcriber (`vars/homepage.yml`, `vars/transcriber.yml` + `vars/transcriber.images.yml`).
|
||||
- Общие переменные из `vars/secrets.yml`: `application_dir`, `bin_prefix`, `primary_user` и др.
|
||||
- Каждое приложение: `app_name`, `app_user`, `app_owner_uid`, `app_owner_gid`, `base_dir`, `data_dir`.
|
||||
- UID/GID сервисов: новое соглашение — диапазон `11xx`, причём `app_owner_uid == app_owner_gid` (одно число на сервис). Новому приложению берём следующий свободный номер по возрастанию. Старые сервисы ещё сидят на легаси-нумерации `10xx` (часто с разными uid/gid) — их не трогаем, но новые заводим только в `11xx`.
|
||||
|
||||
## Линтинг и CI
|
||||
|
||||
|
||||
@@ -720,6 +720,9 @@ access_control:
|
||||
|
||||
rules:
|
||||
## Rules applied to everyone
|
||||
- domain: "start.vakhrushev.me"
|
||||
policy: "one_factor"
|
||||
|
||||
- domain: "status.vakhrushev.me"
|
||||
subject: "group:admins"
|
||||
policy: "two_factor"
|
||||
|
||||
@@ -61,6 +61,22 @@ vakhrushev.me {
|
||||
}
|
||||
|
||||
# Дашборд со списком сервисов (gethomepage). Закрыт за Authelia. Это отдельный
|
||||
# сервис, не путать с кастомной домашней страничкой homepage_app на apex выше.
|
||||
start.vakhrushev.me {
|
||||
tls anwinged@ya.ru
|
||||
import access_log
|
||||
|
||||
forward_auth authelia_app:9091 {
|
||||
uri /api/authz/forward-auth
|
||||
copy_headers Remote-User Remote-Groups Remote-Email Remote-Name
|
||||
}
|
||||
|
||||
reverse_proxy {
|
||||
to dashboard_app:3000
|
||||
}
|
||||
}
|
||||
|
||||
matrix.vakhrushev.me {
|
||||
tls anwinged@ya.ru
|
||||
import access_log
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
# https://gethomepage.dev/configs/bookmarks/
|
||||
- Внешнее:
|
||||
- Yandex Cloud:
|
||||
- abbr: YC
|
||||
href: https://console.cloud.yandex.ru/
|
||||
- Timeweb:
|
||||
- abbr: TW
|
||||
href: https://timeweb.cloud/my
|
||||
@@ -0,0 +1,102 @@
|
||||
# https://gethomepage.dev/configs/services/
|
||||
# href — внешний адрес через Caddy (для браузера);
|
||||
# siteMonitor — внутренний адрес контейнера в web_proxy_network, по нему
|
||||
# homepage рисует индикатор up/down (быстро, без выхода наружу).
|
||||
# icon — бренд-логотипы Dashboard Icons (<name>.png, грузятся браузером
|
||||
# с CDN jsDelivr); где бренда нет — mdi-* из комплекта homepage.
|
||||
|
||||
- Работа и знания:
|
||||
- Gitea:
|
||||
href: https://git.vakhrushev.me
|
||||
description: Git-репозитории
|
||||
icon: gitea.png
|
||||
siteMonitor: http://gitea_app:3000
|
||||
- Outline:
|
||||
href: https://outline.vakhrushev.me
|
||||
description: База знаний / вики
|
||||
icon: outline.png
|
||||
siteMonitor: http://outline_app:3000
|
||||
- Memos:
|
||||
href: https://memos.vakhrushev.me
|
||||
description: Заметки
|
||||
icon: memos.png
|
||||
siteMonitor: http://memos_app:5230
|
||||
- Tududi:
|
||||
href: https://tududi.vakhrushev.me
|
||||
description: Планировщик задач
|
||||
icon: tududi.png
|
||||
siteMonitor: http://tududi_app:3002
|
||||
- Wakapi:
|
||||
href: https://wakapi.vakhrushev.me
|
||||
description: Трекинг времени в коде
|
||||
icon: wakapi.png
|
||||
siteMonitor: http://wakapi_app:3000
|
||||
|
||||
- Медиа и хобби:
|
||||
- Miniflux:
|
||||
href: https://miniflux.vakhrushev.me
|
||||
description: RSS-ридер
|
||||
icon: miniflux.png
|
||||
siteMonitor: http://miniflux_app:8080
|
||||
- RSS-Bridge:
|
||||
href: https://rssbridge.vakhrushev.me
|
||||
description: Генератор RSS для сайтов без фидов
|
||||
icon: rss-bridge.png
|
||||
siteMonitor: http://rssbridge_app:80
|
||||
- Calibre:
|
||||
href: https://calibre.vakhrushev.me
|
||||
description: Электронная библиотека
|
||||
icon: calibre-web.png
|
||||
siteMonitor: http://calibre_web_app:8083
|
||||
- Gramps:
|
||||
href: https://gramps.vakhrushev.me
|
||||
description: Генеалогия
|
||||
icon: gramps-web.png
|
||||
siteMonitor: http://gramps_app:5000
|
||||
- Wanderer:
|
||||
href: https://wanderer.vakhrushev.me
|
||||
description: Пешие маршруты
|
||||
icon: wanderer.png
|
||||
siteMonitor: http://wanderer_web:3000
|
||||
- Remembos:
|
||||
href: https://remembos.vakhrushev.me
|
||||
description: Интервальное повторение
|
||||
icon: mdi-brain
|
||||
siteMonitor: http://remembos_app:8080
|
||||
- Matrix:
|
||||
href: https://matrix.vakhrushev.me
|
||||
description: Мессенджер (Tuwunel)
|
||||
icon: matrix.png
|
||||
siteMonitor: http://tuwunel_app:6167
|
||||
|
||||
- Инфраструктура:
|
||||
- Netdata:
|
||||
href: https://status.vakhrushev.me
|
||||
description: Мониторинг сервера
|
||||
icon: netdata.png
|
||||
siteMonitor: http://netdata:19999
|
||||
- Dozzle:
|
||||
href: https://dozzle.vakhrushev.me
|
||||
description: Логи контейнеров
|
||||
icon: dozzle.png
|
||||
siteMonitor: http://dozzle_app:8080
|
||||
- GoAccess:
|
||||
href: https://goaccess.vakhrushev.me
|
||||
description: Веб-аналитика логов Caddy
|
||||
icon: goaccess.png
|
||||
siteMonitor: http://goaccess_app:8080
|
||||
- Bifrost:
|
||||
href: https://bifrost.vakhrushev.me
|
||||
description: LLM-шлюз (DeepSeek)
|
||||
icon: mdi-transit-connection-variant
|
||||
siteMonitor: http://bifrost_app:8080/health
|
||||
- Authelia:
|
||||
href: https://auth.vakhrushev.me
|
||||
description: SSO / аутентификация
|
||||
icon: authelia.png
|
||||
siteMonitor: http://authelia_app:9091
|
||||
- Wanderbase:
|
||||
href: https://wanderbase.vakhrushev.me
|
||||
description: PocketBase — бэкенд Wanderer
|
||||
icon: pocketbase.png
|
||||
siteMonitor: http://wanderer_db:8090
|
||||
@@ -0,0 +1,22 @@
|
||||
# https://gethomepage.dev/configs/settings/
|
||||
title: Сервер vakhrushev.me
|
||||
headerStyle: clean
|
||||
theme: dark
|
||||
color: slate
|
||||
|
||||
# Порядок в layout = порядок групп на странице (сверху вниз). style: row +
|
||||
# columns: 3 — каждая группа во всю ширину, карточки по 3 в ряд. Блок закладок
|
||||
# «Внешнее» указан последним, поэтому остаётся внизу.
|
||||
layout:
|
||||
Работа и знания:
|
||||
style: row
|
||||
columns: 3
|
||||
Медиа и хобби:
|
||||
style: row
|
||||
columns: 3
|
||||
Инфраструктура:
|
||||
style: row
|
||||
columns: 3
|
||||
Внешнее:
|
||||
style: row
|
||||
columns: 3
|
||||
@@ -0,0 +1,8 @@
|
||||
# https://gethomepage.dev/configs/info-widgets/
|
||||
# Метрики хоста homepage читает из /proc внутри контейнера — в docker это
|
||||
# общий с хостом kernel, поэтому cpu/memory отражают сервер целиком.
|
||||
- resources:
|
||||
label: "{{ host_name }}"
|
||||
cpu: true
|
||||
memory: true
|
||||
expanded: true
|
||||
@@ -0,0 +1,27 @@
|
||||
# dashboard (gethomepage.dev) — стартовая страница со списком сервисов.
|
||||
# Контейнер в web_proxy_network, слушает {{ homepage_port }}, наружу НЕ
|
||||
# публикуется — доступ только через Caddy как https://{{ homepage_domain }}
|
||||
# (закрыт за Authelia). Это отдельный сервис, не связан с кастомным homepage_app
|
||||
# на apex vakhrushev.me.
|
||||
|
||||
services:
|
||||
|
||||
dashboard_app:
|
||||
image: "{{ homepage_image }}"
|
||||
container_name: dashboard_app
|
||||
restart: unless-stopped
|
||||
user: "{{ app_owner_uid }}:{{ app_owner_gid }}"
|
||||
networks:
|
||||
- "web_proxy_network"
|
||||
volumes:
|
||||
- "{{ config_dir }}:/app/config"
|
||||
- "/etc/localtime:/etc/localtime:ro"
|
||||
- "/etc/timezone:/etc/timezone:ro"
|
||||
environment:
|
||||
# homepage 1.x требует явный whitelist Host за реверс-прокси, иначе отдаёт
|
||||
# «Host validation failed». Пускаем только адрес из Caddy.
|
||||
- HOMEPAGE_ALLOWED_HOSTS={{ homepage_domain }}
|
||||
|
||||
networks:
|
||||
web_proxy_network:
|
||||
external: true
|
||||
@@ -54,6 +54,9 @@
|
||||
- name: "Configure homepage"
|
||||
ansible.builtin.import_playbook: playbook-homepage.yml
|
||||
|
||||
- name: "Configure dashboard"
|
||||
ansible.builtin.import_playbook: playbook-dashboard.yml
|
||||
|
||||
- name: "Configure transcriber"
|
||||
ansible.builtin.import_playbook: playbook-transcriber.yml
|
||||
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
---
|
||||
- name: "Configure dashboard start page"
|
||||
hosts: all
|
||||
|
||||
vars_files:
|
||||
- vars/secrets.yml
|
||||
- vars/vars.yml
|
||||
|
||||
vars:
|
||||
app_name: "dashboard"
|
||||
app_user: "{{ app_name }}"
|
||||
app_owner_uid: 1109
|
||||
app_owner_gid: 1109
|
||||
base_dir: "{{ (application_dir, app_name) | path_join }}"
|
||||
config_dir: "{{ (base_dir, 'config') | path_join }}"
|
||||
|
||||
# gethomepage.dev — проверь актуальный тег перед обновлением.
|
||||
homepage_image: "ghcr.io/gethomepage/homepage:v1.13.2"
|
||||
# Внутренний порт контейнера; наружу не публикуется, ходим только через Caddy.
|
||||
homepage_port: 3000
|
||||
# Домен, на котором Caddy отдаёт дашборд. homepage 1.x требует явный whitelist
|
||||
# Host за реверс-прокси, иначе «Host validation failed».
|
||||
homepage_domain: "start.vakhrushev.me"
|
||||
|
||||
config_files:
|
||||
- "settings"
|
||||
- "services"
|
||||
- "widgets"
|
||||
- "bookmarks"
|
||||
|
||||
tasks:
|
||||
- name: "Create user and environment"
|
||||
ansible.builtin.import_role:
|
||||
name: owner
|
||||
vars:
|
||||
owner_name: "{{ app_user }}"
|
||||
owner_uid: "{{ app_owner_uid }}"
|
||||
owner_gid: "{{ app_owner_gid }}"
|
||||
owner_extra_groups: ["docker"]
|
||||
|
||||
- name: "Create application internal directories"
|
||||
ansible.builtin.file:
|
||||
path: "{{ item }}"
|
||||
state: "directory"
|
||||
owner: "{{ app_user }}"
|
||||
group: "{{ app_user }}"
|
||||
mode: "0750"
|
||||
loop:
|
||||
- "{{ base_dir }}"
|
||||
- "{{ config_dir }}"
|
||||
|
||||
- name: "Render dashboard config files"
|
||||
ansible.builtin.template:
|
||||
src: "./files/{{ app_name }}/config/{{ item }}.template.yaml"
|
||||
dest: "{{ (config_dir, item ~ '.yaml') | path_join }}"
|
||||
owner: "{{ app_user }}"
|
||||
group: "{{ app_user }}"
|
||||
mode: "0640"
|
||||
loop: "{{ config_files }}"
|
||||
|
||||
- name: "Copy docker compose file"
|
||||
ansible.builtin.template:
|
||||
src: "./files/{{ app_name }}/docker-compose.template.yml"
|
||||
dest: "{{ base_dir }}/docker-compose.yml"
|
||||
owner: "{{ app_user }}"
|
||||
group: "{{ app_user }}"
|
||||
mode: "0640"
|
||||
|
||||
- name: "Run application with docker compose"
|
||||
community.docker.docker_compose_v2:
|
||||
project_src: "{{ base_dir }}"
|
||||
state: "present"
|
||||
remove_orphans: true
|
||||
pull: "always"
|
||||
tags:
|
||||
- run-app
|
||||
Reference in New Issue
Block a user