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-wakapi.yml` — трекинг времени.
|
||||||
- `playbook-memos.yml` — заметки.
|
- `playbook-memos.yml` — заметки.
|
||||||
- `playbook-outline.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-rssbridge.yml` — RSS-агрегатор.
|
||||||
- `playbook-netdata.yml` — мониторинг.
|
- `playbook-netdata.yml` — мониторинг.
|
||||||
- `playbook-dozzle.yml` — просмотр Docker-логов.
|
- `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`).
|
- Большинство приложений определяют переменные inline в плейбуке. Отдельные файлы переменных только у homepage и transcriber (`vars/homepage.yml`, `vars/transcriber.yml` + `vars/transcriber.images.yml`).
|
||||||
- Общие переменные из `vars/secrets.yml`: `application_dir`, `bin_prefix`, `primary_user` и др.
|
- Общие переменные из `vars/secrets.yml`: `application_dir`, `bin_prefix`, `primary_user` и др.
|
||||||
- Каждое приложение: `app_name`, `app_user`, `app_owner_uid`, `app_owner_gid`, `base_dir`, `data_dir`.
|
- Каждое приложение: `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
|
## Линтинг и CI
|
||||||
|
|
||||||
|
|||||||
@@ -720,6 +720,9 @@ access_control:
|
|||||||
|
|
||||||
rules:
|
rules:
|
||||||
## Rules applied to everyone
|
## Rules applied to everyone
|
||||||
|
- domain: "start.vakhrushev.me"
|
||||||
|
policy: "one_factor"
|
||||||
|
|
||||||
- domain: "status.vakhrushev.me"
|
- domain: "status.vakhrushev.me"
|
||||||
subject: "group:admins"
|
subject: "group:admins"
|
||||||
policy: "two_factor"
|
policy: "two_factor"
|
||||||
|
|||||||
@@ -61,6 +61,22 @@ vakhrushev.me {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Дашборд со списком сервисов (gethomepage). Закрыт за Authelia. Это отдельный
|
# Дашборд со списком сервисов (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
|
tls anwinged@ya.ru
|
||||||
import access_log
|
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"
|
- name: "Configure homepage"
|
||||||
ansible.builtin.import_playbook: playbook-homepage.yml
|
ansible.builtin.import_playbook: playbook-homepage.yml
|
||||||
|
|
||||||
|
- name: "Configure dashboard"
|
||||||
|
ansible.builtin.import_playbook: playbook-dashboard.yml
|
||||||
|
|
||||||
- name: "Configure transcriber"
|
- name: "Configure transcriber"
|
||||||
ansible.builtin.import_playbook: playbook-transcriber.yml
|
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