Prepare BentoPDF and Grafana InfluxDB stacks

Prepare BentoPDF and Grafana InfluxDB stacks
This commit is contained in:
2026-04-30 10:29:53 +02:00
parent f3dd51de14
commit 8a43914d05
12 changed files with 230 additions and 42 deletions
+13 -3
View File
@@ -101,7 +101,7 @@ traefik (80/443)
└── frontend_net
├── öffentliche Apps (vaultwarden, mealie, paperless, immich, gitea, ntfy, mail-archiver, nextcloud)
├── geschützte UIs mit Middleware (homepage, paperless-gpt, uptime-kuma, filebrowser, scrutiny, code-server, backrest, borg-ui, glances, speedtest, stirling-pdf)
├── geschützte UIs mit Middleware (homepage, paperless-gpt, uptime-kuma, filebrowser, scrutiny, code-server, backrest, borg-ui, glances, speedtest, bentopdf, grafana)
├── Admin-UI mit nativer Auth (komodo)
└── Dienste mit Internetbedarf ohne öffentliche UI (ddns-updater)
@@ -156,7 +156,8 @@ Diese Dienste sind **keine Public Apps**:
- `paperless-gpt` — paperless-gpt.kaleschke.info (Middleware)
- `glances` — glances.kaleschke.info (Middleware)
- `speedtest-tracker` — speedtest.kaleschke.info (Middleware)
- `stirling-pdf` — pdf.kaleschke.info (Middleware)
- `bentopdf` — pdf.kaleschke.info (Middleware)
- `grafana` — grafana.kaleschke.info (Middleware)
- `Traefik-Dashboard`
- `AdGuard Home` — Port 8082 direkt auf die Admin-UI (`80` im Container), kein Traefik, nur LAN-Zugang
@@ -279,7 +280,7 @@ Legende Status:
| `filebrowser` | ✅ | `frontend_net` | Traefik + Middleware | aktiv via `files.kaleschke.info` | Mounts einschränken (Block F) |
| `borg-ui` | ✅ | `frontend_net` | Traefik + Middleware | produktiver Borg-/Restore-Dienst; `/local/secrets` ist bewusst Teil des Restore-Scopes | BorgBase-Repo und Key laufend pflegen |
| `paperless-gpt` | ✅ | `frontend_net` | Traefik + Middleware | aktiv via `paperless-gpt.kaleschke.info` | — |
| `stirling-pdf` | ✅ | `frontend_net` | Traefik + Middleware | PDF-Tooling via `pdf.kaleschke.info`; lokale Stirling-Auth deaktiviert zugunsten zentraler Auth | — |
| `bentopdf` | ✅ vorbereitet | `frontend_net` | Traefik + Middleware | PDF-Tooling via `pdf.kaleschke.info`; browserseitige Verarbeitung, COOP/COEP fuer Office-Konvertierung | Deploy und fachliche Abnahme offen |
### 7.6 Monitoring / Status
@@ -289,6 +290,8 @@ Legende Status:
| `glances` | ✅ | `frontend_net` | Traefik + Middleware | aktiv via `glances.kaleschke.info` | — |
| `scrutiny` | ✅ | `frontend_net` | Traefik + Middleware | aktiv via `scrutiny.kaleschke.info`, Git-Stack | `privileged` später prüfen |
| `speedtest-tracker` | ✅ | `frontend_net` | Traefik + Middleware | aktiv via `speedtest.kaleschke.info` | — |
| `grafana` | ✅ vorbereitet | `frontend_net`, `grafana_influx_internal` | Traefik + Middleware | vorbereitet via `grafana.kaleschke.info`, InfluxDB-Datenquelle provisioniert | Secrets anlegen, Deploy offen |
| `influxdb3-core` | ✅ vorbereitet | `grafana_influx_internal` | intern | InfluxDB 3 Core fuer Metriken; keine direkte Host-/Traefik-Freigabe | Token und Datenbank `homelab` anlegen, Deploy offen |
### 7.7 Noch offene Sonderfälle
@@ -522,6 +525,13 @@ Mutable Tags wie `latest`, `stable`, `release` oder reine Major-Tags wurden auf
- `nextcloud` bleibt bei nativer App-Authentifizierung ohne zentrale ForwardAuth-Middleware vor dem Router, damit Browser-Login, Desktop-/Mobile-Clients sowie WebDAV/CardDAV sauber funktionieren.
- `stirling-pdf` wird als geschuetzter Tool-Stack hinter `authelia@file,secure-headers@file` betrieben; die interne Stirling-Login-Funktion bleibt deaktiviert, um Doppel-Login zu vermeiden.
### BentoPDF und Grafana/InfluxDB vorbereitet (2026-04-30)
- `bentopdf` ersetzt repo-seitig `stirling-pdf` auf der bestehenden Domain `pdf.kaleschke.info`, bleibt aber bis zum bewussten Komodo-Deploy nur vorbereitet.
- BentoPDF benoetigt fuer Office-Konvertierung die Cross-Origin-Isolation-Header `Cross-Origin-Opener-Policy: same-origin` und `Cross-Origin-Embedder-Policy: require-corp`; diese werden per Traefik-Docker-Middleware gesetzt.
- `grafana` wird als geschuetztes Monitoring-UI unter `grafana.kaleschke.info` vorbereitet.
- `influxdb3-core` bleibt als interne Datenbank ohne direkten Host-Port im Compose-internen Netz `grafana_influx_internal`.
- InfluxDB 3 Core nutzt einen festen Versionstag statt `latest`, weil der InfluxDB-`latest`-Tag versionsstrategisch im Umbruch ist.
### ddns-updater — Netz-Ausnahme
Bleibt bewusst in `frontend_net` statt `backend_net`, weil `backend_net` `internal: true` ist und ddns-updater die Cloudflare-API erreichen muss.
+1 -1
View File
@@ -64,4 +64,4 @@ Bei Restore-, Host-Ausfall- oder Wiederanlauf-Fragen zusaetzlich:
- Mutable Image-Tags sind auf die aktuell laufenden Digests eingefroren; echte Versions-Upgrades erfolgen bewusst separat.
- Disaster-Recovery und dienstspezifische Restore-Quellen sind in `docs/DISASTER_RECOVERY.md` und `docs/RESTORE_MATRIX.md` beschrieben.
- Der verbindliche Detailablauf steht in `docs/WORKFLOW.md`.
- `nextcloud` und `stirling-pdf` sind repo-seitig vorbereitet und folgen dem dokumentierten Netz-/Secret-/Traefik-Modell.
- `nextcloud`, `bentopdf` und `grafana-influxdb` sind repo-seitig vorbereitet und folgen dem dokumentierten Netz-/Secret-/Traefik-Modell.
+35
View File
@@ -0,0 +1,35 @@
services:
bentopdf:
image: bentopdfteam/bentopdf:2.8.4
container_name: bentopdf
restart: unless-stopped
read_only: true
tmpfs:
- /tmp
- /var/cache/nginx
- /var/run
networks:
- frontend_net
security_opt:
- no-new-privileges:true
healthcheck:
test: ["CMD", "wget", "--spider", "-q", "http://localhost:8080"]
interval: 30s
timeout: 10s
retries: 3
start_period: 20s
labels:
- traefik.enable=true
- traefik.docker.network=frontend_net
- traefik.http.routers.bentopdf.rule=Host(`pdf.kaleschke.info`)
- traefik.http.routers.bentopdf.entrypoints=websecure
- traefik.http.routers.bentopdf.tls=true
- traefik.http.routers.bentopdf.tls.certresolver=le
- traefik.http.routers.bentopdf.middlewares=authelia@file,secure-headers@file,bentopdf-coi@docker
- traefik.http.middlewares.bentopdf-coi.headers.customresponseheaders.Cross-Origin-Opener-Policy=same-origin
- traefik.http.middlewares.bentopdf-coi.headers.customresponseheaders.Cross-Origin-Embedder-Policy=require-corp
- traefik.http.services.bentopdf.loadbalancer.server.port=8080
networks:
frontend_net:
external: true
-35
View File
@@ -1,35 +0,0 @@
services:
stirling-pdf:
image: stirlingtools/stirling-pdf:2.9.2
container_name: stirling-pdf
restart: unless-stopped
environment:
DISABLE_ADDITIONAL_FEATURES: "false"
SECURITY_ENABLELOGIN: "false"
LANGS: de_DE
SYSTEM_DEFAULTLOCALE: de-DE
SYSTEM_GOOGLEVISIBILITY: "false"
SYSTEM_ROOTURIPATH: /
volumes:
- /mnt/user/appdata/stirling-pdf/tessdata:/usr/share/tessdata
- /mnt/user/appdata/stirling-pdf/configs:/configs
- /mnt/user/appdata/stirling-pdf/logs:/logs
- /mnt/user/appdata/stirling-pdf/customFiles:/customFiles
- /mnt/user/appdata/stirling-pdf/pipeline:/pipeline
networks:
- frontend_net
security_opt:
- no-new-privileges:true
labels:
- "traefik.enable=true"
- "traefik.docker.network=frontend_net"
- "traefik.http.routers.stirling-pdf.rule=Host(`pdf.kaleschke.info`)"
- "traefik.http.routers.stirling-pdf.entrypoints=websecure"
- "traefik.http.routers.stirling-pdf.tls=true"
- "traefik.http.routers.stirling-pdf.tls.certresolver=le"
- "traefik.http.routers.stirling-pdf.middlewares=authelia@file,secure-headers@file"
- "traefik.http.services.stirling-pdf.loadbalancer.server.port=8080"
networks:
frontend_net:
external: true
+3 -2
View File
@@ -257,7 +257,7 @@ Ziel:
15. `apps/homepage/`
16. `apps/ntfy/`
17. `apps/paperless-gpt/`
18. `apps/stirling-pdf/`
18. `apps/bentopdf/`
19. `ops/uptime-kuma/`
20. `ops/borg-ui/`
21. `ops/backrest/`
@@ -265,7 +265,8 @@ Ziel:
23. `ops/glances/`
24. `ops/scrutiny/`
25. `ops/speedtest/`
26. `infra/ddns-updater/`
26. `ops/grafana-influxdb/`
27. `infra/ddns-updater/`
**Regel:** Nach jeder Stufe kurz pruefen, bevor die naechste beginnt.
+9
View File
@@ -67,6 +67,15 @@ Dieses Dokument ist nur noch ein historischer Verlauf. Der aktuelle operative Ab
- `apps/stirling-pdf/docker-compose.yml` als geschuetzter Tool-Stack hinter `authelia@file,secure-headers@file` vorbereitet.
- Stirling-PDF nutzt persistente Pfade fuer `/configs`, `/logs`, `/pipeline`, `/customFiles` und `/usr/share/tessdata`; interne Stirling-Login-Funktion bleibt zugunsten des zentralen Traefik-/Authelia-Zugangs deaktiviert.
### 2026-04-30 - BentoPDF und Grafana/InfluxDB vorbereitet
- `stirling-pdf` repo-seitig durch `bentopdf` ersetzt; Domain `pdf.kaleschke.info` bleibt erhalten.
- BentoPDF laeuft als geschuetztes browserseitiges PDF-Tool hinter `authelia@file,secure-headers@file` und setzt zusaetzlich COOP/COEP-Header fuer SharedArrayBuffer-basierte Office-Konvertierung.
- `ops/grafana-influxdb` als neuer Monitoring-Stack vorbereitet, aber noch nicht deployed.
- Grafana wird hinter Traefik + Authelia unter `grafana.kaleschke.info` geplant.
- InfluxDB 3 Core bleibt intern im Compose-Netz und wird ueber eine provisionierte Grafana-Datenquelle angebunden.
- Secrets fuer Grafana-Admin-Passwort, InfluxDB-Admin-Token und Grafana-Datasource-Token sind dokumentiert, aber muessen vor dem ersten Deploy auf dem Host bzw. in Komodo angelegt werden.
---
## Dauerhafte Learnings
+3 -1
View File
@@ -64,7 +64,9 @@ Sie ist die fachliche Ergaenzung zu `docs/DISASTER_RECOVERY.md`.
| Glances | Rebuildbar | kein kritischer Zustand | keine | keine | Traefik, Authelia | UI startet |
| Scrutiny | Teilweise rebuildbar | `/mnt/user/appdata/scrutiny` falls gewuenscht | InfluxDB bewusst nicht Teil des Critical-Scope | keine | Traefik, Authelia | UI startet, Laufwerke sichtbar |
| Speedtest Tracker | Share | `/mnt/user/appdata/speedtest-tracker/config` | SQLite im App-Pfad | `APP_KEY`, `ADMIN_PASSWORD` | Traefik, Authelia | UI startet |
| Stirling-PDF | Share | `/mnt/user/appdata/stirling-pdf/configs`, `/mnt/user/appdata/stirling-pdf/logs`, `/mnt/user/appdata/stirling-pdf/customFiles`, `/mnt/user/appdata/stirling-pdf/pipeline`, `/mnt/user/appdata/stirling-pdf/tessdata` | keine | keine separaten Secret-Dateien dokumentiert | Traefik, Authelia | UI startet, PDF-Tools verfuegbar |
| BentoPDF | Rebuildbar | keine kritische Persistenz; alte Stirling-PDF-Daten unter `/mnt/user/appdata/stirling-pdf` bis zur Abnahme behalten | keine | keine separaten Secret-Dateien dokumentiert | Traefik, Authelia | UI startet, PDF-Tools verfuegbar, Office-Konvertierung ueber HTTPS funktioniert |
| Grafana | Share | `/mnt/user/appdata/grafana` | SQLite im App-Pfad | `grafana_admin_password.txt`, `GRAFANA_INFLUXDB_TOKEN` | Traefik, Authelia, InfluxDB 3 Core | UI startet, InfluxDB-Datenquelle testet erfolgreich |
| InfluxDB 3 Core | Share | `/mnt/user/appdata/influxdb3/data`, `/mnt/user/appdata/influxdb3/plugins` | dateibasierter Object Store | `influxdb3_admin_token.json` | internes `grafana_influx_internal` Netz | `homelab`-Datenbank vorhanden, Grafana kann SQL-Abfrage ausfuehren |
| ddns-updater | Rebuildbar | geringe Persistenzrelevanz | keine | Provider-Zugang ueber Stack ENV | Internetzugang | Update-Job laeuft |
---
+22
View File
@@ -72,6 +72,28 @@ Bei Problemen mit Borg UI oder Dump-Automatisierung:
3. Persistenz unter `/mnt/user/appdata/borg-ui/` und `/mnt/user/backups/borg/dumps/` nicht blind loeschen
4. Restore zuerst in einen Testpfad schreiben, nicht direkt in Produktivpfade
## BentoPDF / Stirling-PDF Rollback
Bei Problemen mit BentoPDF:
1. Git-Stand auf die letzte funktionierende Stirling-PDF-Compose zuruecknehmen oder gezielt `apps/bentopdf` wieder durch `apps/stirling-pdf` ersetzen
2. Commit + Push nach Gitea
3. betroffenen Stack in Komodo redeployen
4. `https://pdf.kaleschke.info` pruefen
Die alte Stirling-PDF-Persistenz unter `/mnt/user/appdata/stirling-pdf` nicht loeschen, solange der BentoPDF-Ersatz nicht fachlich abgenommen ist.
## Grafana / InfluxDB Rollback
Vor dem ersten produktiven Einsatz reicht es, den vorbereiteten Stack nicht zu deployen oder per Ruecknahme-Commit aus dem Repo zu entfernen.
Nach einem Deploy:
1. `ops/grafana-influxdb` in Komodo stoppen oder den letzten Git-Stand ohne diesen Stack deployen
2. Persistenz unter `/mnt/user/appdata/grafana` und `/mnt/user/appdata/influxdb3` unangetastet lassen
3. Secrets unter `/mnt/user/appdata/secrets/grafana_admin_password.txt` und `/mnt/user/appdata/secrets/influxdb3_admin_token.json` nur nach bewusstem Entscheid entfernen
4. Grafana-Domain und InfluxDB-Zugriff testen, bis klar ist, dass keine produktiven Dashboards oder Writer mehr davon abhaengen
---
## Daten-Rollback
+5
View File
@@ -43,6 +43,9 @@ Dieses Dokument listet sensible Daten, deren Ablageorte und die vorgesehene Einb
| Borg UI / Borg | Admin-Login, `SECRET_KEY`, SSH-Keys, Repo-Credentials | persistent unter `/mnt/user/appdata/borg-ui/data/` | aktiv |
| Hermes Agent | Provider-Keys, Bot-Tokens, API-Server-Key | `/mnt/user/appdata/hermes-agent/data/.env` | neu |
| Hermes Agent | SSH-Runner Private Key | `/mnt/user/appdata/secrets/hermes_runner_id_ed25519` -> `/root/.ssh/id_ed25519` | neu |
| Grafana | Admin Password | `/mnt/user/appdata/secrets/grafana_admin_password.txt` -> `GF_SECURITY_ADMIN_PASSWORD__FILE` | vorbereitet |
| InfluxDB 3 Core | Admin Token JSON | `/mnt/user/appdata/secrets/influxdb3_admin_token.json` -> Docker Secret `/run/secrets/influxdb3_admin_token` | vorbereitet |
| Grafana -> InfluxDB | Datasource Token | Stack ENV `${GRAFANA_INFLUXDB_TOKEN}` | vorbereitet |
---
@@ -71,6 +74,8 @@ Dieses Dokument listet sensible Daten, deren Ablageorte und die vorgesehene Einb
|-- nextcloud_postgres_password.txt
|-- postgres_password.txt
|-- redis_password.txt
|-- grafana_admin_password.txt
|-- influxdb3_admin_token.json
`-- vaultwarden_admin_token.txt
```
+50
View File
@@ -0,0 +1,50 @@
# Grafana + InfluxDB 3 Core
Vorbereiteter Monitoring-Stack. Noch nicht deployen, bis die Secrets und der erste InfluxDB-Token sauber angelegt sind.
## Quellen / Entscheidungen
- Grafana nutzt das offizielle OSS-Image `grafana/grafana:12.4.3`.
- InfluxDB nutzt `influxdb:3.9.1-core`, nicht `latest`, weil `latest` bei InfluxDB aktiv in Richtung InfluxDB 3 umgestellt wird.
- Grafana wird ueber Traefik + `authelia@file,secure-headers@file` unter `grafana.kaleschke.info` veroeffentlicht.
- InfluxDB bleibt ohne direkten Host-Port und ohne Traefik-Route im internen Compose-Netz `grafana_influx_internal`.
- Grafana provisioning legt eine SQL-Datenquelle fuer InfluxDB 3 Core mit der Datenbank `homelab` an.
## Vor dem ersten Deploy
1. Secret fuer Grafana anlegen:
```bash
install -m 600 /dev/null /mnt/user/appdata/secrets/grafana_admin_password.txt
```
2. Offline-Admin-Token fuer InfluxDB 3 als JSON anlegen:
```json
{
"token": "apiv3_REPLACE_WITH_STRONG_RANDOM_TOKEN",
"name": "admin",
"description": "Admin token for KalliLab InfluxDB 3 Core"
}
```
Pfad: `/mnt/user/appdata/secrets/influxdb3_admin_token.json`, Rechte `600`.
3. In Komodo fuer den Stack `GRAFANA_INFLUXDB_TOKEN` setzen. Fuer den Start kann das derselbe Token aus `influxdb3_admin_token.json` sein; sauberer ist spaeter ein eigener Read-Token fuer Grafana.
4. Nach dem ersten Start die Datenbank anlegen:
```bash
docker exec influxdb3-core influxdb3 create database homelab --token "$INFLUXDB3_AUTH_TOKEN"
```
## Smoke-Test nach Deploy
- `https://grafana.kaleschke.info` oeffnet nach Authelia die Grafana-Loginseite.
- Grafana `Connections -> Data sources -> InfluxDB 3 Core -> Save & test` ist erfolgreich.
- InfluxDB bleibt von aussen nicht direkt erreichbar.
## Rollback
- Stack in Komodo stoppen oder Git auf den letzten Stand ohne `ops/grafana-influxdb` zuruecknehmen.
- Persistente Daten liegen unter `/mnt/user/appdata/grafana` und `/mnt/user/appdata/influxdb3`; nicht automatisch loeschen.
+71
View File
@@ -0,0 +1,71 @@
services:
grafana:
image: grafana/grafana:12.4.3
container_name: grafana
restart: unless-stopped
user: "0"
environment:
GF_SERVER_ROOT_URL: https://grafana.kaleschke.info/
GF_SECURITY_ADMIN_PASSWORD__FILE: /run/secrets/grafana_admin_password
GF_USERS_ALLOW_SIGN_UP: "false"
GF_AUTH_ANONYMOUS_ENABLED: "false"
GRAFANA_INFLUXDB_TOKEN: ${GRAFANA_INFLUXDB_TOKEN}
volumes:
- /mnt/user/appdata/grafana:/var/lib/grafana
- ./provisioning:/etc/grafana/provisioning:ro
secrets:
- grafana_admin_password
networks:
- frontend_net
- grafana_influx_internal
security_opt:
- no-new-privileges:true
healthcheck:
test: ["CMD", "wget", "--spider", "-q", "http://localhost:3000/api/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
labels:
- traefik.enable=true
- traefik.docker.network=frontend_net
- traefik.http.routers.grafana.rule=Host(`grafana.kaleschke.info`)
- traefik.http.routers.grafana.entrypoints=websecure
- traefik.http.routers.grafana.tls=true
- traefik.http.routers.grafana.tls.certresolver=le
- traefik.http.routers.grafana.middlewares=authelia@file,secure-headers@file
- traefik.http.services.grafana.loadbalancer.server.port=3000
influxdb3-core:
image: influxdb:3.9.1-core
container_name: influxdb3-core
restart: unless-stopped
command:
- influxdb3
- serve
- --node-id=kallilabcore
- --object-store=file
- --data-dir=/var/lib/influxdb3/data
- --plugin-dir=/var/lib/influxdb3/plugins
- --admin-token-file=/run/secrets/influxdb3_admin_token
volumes:
- /mnt/user/appdata/influxdb3/data:/var/lib/influxdb3/data
- /mnt/user/appdata/influxdb3/plugins:/var/lib/influxdb3/plugins
secrets:
- influxdb3_admin_token
networks:
- grafana_influx_internal
security_opt:
- no-new-privileges:true
secrets:
grafana_admin_password:
file: /mnt/user/appdata/secrets/grafana_admin_password.txt
influxdb3_admin_token:
file: /mnt/user/appdata/secrets/influxdb3_admin_token.json
networks:
frontend_net:
external: true
grafana_influx_internal:
internal: true
@@ -0,0 +1,18 @@
apiVersion: 1
prune: true
datasources:
- name: InfluxDB 3 Core
uid: influxdb3-core
type: influxdb
access: proxy
url: http://influxdb3-core:8181
isDefault: true
jsonData:
version: SQL
dbName: homelab
httpMode: POST
insecureGrpc: true
secureJsonData:
token: $GRAFANA_INFLUXDB_TOKEN