Add Dawarich stack
This commit is contained in:
+2
-1
@@ -6,7 +6,8 @@
|
|||||||
!**/stack.env.example
|
!**/stack.env.example
|
||||||
|
|
||||||
# Secrets and certificate material
|
# Secrets and certificate material
|
||||||
**/secrets/
|
**/secrets/*
|
||||||
|
!**/secrets/*.example
|
||||||
**/letsencrypt/
|
**/letsencrypt/
|
||||||
**/acme.json
|
**/acme.json
|
||||||
**/*.key
|
**/*.key
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
COMPOSE_PROJECT_NAME=dawarich
|
||||||
|
|
||||||
|
TZ=Europe/Berlin
|
||||||
|
DAWARICH_HOST=dawarich.kaleschke.info
|
||||||
|
APPLICATION_HOSTS=dawarich.kaleschke.info
|
||||||
|
|
||||||
|
POSTGRES_USER=dawarich
|
||||||
|
POSTGRES_DB=dawarich_production
|
||||||
|
GRAFANA_DB_USER=dawarich_grafana_ro
|
||||||
|
|
||||||
|
METRICS_USERNAME=prometheus
|
||||||
|
BACKGROUND_PROCESSING_CONCURRENCY=5
|
||||||
|
RAILS_MAX_THREADS=10
|
||||||
@@ -0,0 +1,152 @@
|
|||||||
|
# Dawarich Stack
|
||||||
|
|
||||||
|
Produktionsvorlage fuer Dawarich im KalliLab-Homelab mit GitOps ueber Gitea und Komodo.
|
||||||
|
|
||||||
|
## Gepruefter Stand
|
||||||
|
|
||||||
|
- Dawarich Release: `1.8.1` (GitHub latest am 2026-06-11)
|
||||||
|
- Docker Image: `freikin/dawarich:1.8.1`
|
||||||
|
- Hinweis: `freika/dawarich` existiert auf Docker Hub nicht; das offizielle Image aus dem Upstream-Compose ist `freikin/dawarich`.
|
||||||
|
- Dawarich Tracking-Endpoint fuer OwnTracks: `/api/v1/owntracks/points?api_key=<api-key>`
|
||||||
|
- Dawarich Prometheus ab 1.7.7: `dawarich_app:3000/metrics`; Port `9394` ist intern fuer Sidekiq-Metriken.
|
||||||
|
|
||||||
|
Quellen:
|
||||||
|
|
||||||
|
- https://github.com/Freika/dawarich/releases/tag/1.8.1
|
||||||
|
- https://dawarich.app/docs/getting-started/track-your-location/
|
||||||
|
- https://dawarich.app/docs/self-hosting/monitoring/prometheus/
|
||||||
|
|
||||||
|
## Dateien
|
||||||
|
|
||||||
|
```text
|
||||||
|
apps/dawarich/
|
||||||
|
|-- docker-compose.yml
|
||||||
|
|-- .env.example
|
||||||
|
|-- prometheus-scrape.snippet.yml
|
||||||
|
|-- homeassistant-dawarich.example.yaml
|
||||||
|
|-- grafana/
|
||||||
|
| |-- datasource-dawarich.yml
|
||||||
|
| `-- dashboard-dawarich.json
|
||||||
|
|-- postgres/initdb/20-grafana-readonly.sh
|
||||||
|
`-- secrets/*.txt.example
|
||||||
|
```
|
||||||
|
|
||||||
|
## Setup-Reihenfolge
|
||||||
|
|
||||||
|
1. Stack-Verzeichnis nach Komodo/Gitea uebernehmen: `apps/dawarich`.
|
||||||
|
2. `.env.example` als nicht versionierte Stack-`.env` oder Komodo Stack Environment anlegen.
|
||||||
|
3. Secret-Dateien auf dem Unraid-Host erstellen:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
install -d -m 700 /mnt/user/appdata/secrets
|
||||||
|
openssl rand -base64 48 > /mnt/user/appdata/secrets/dawarich_postgres_password.txt
|
||||||
|
openssl rand -base64 48 | tr -dc 'A-Za-z0-9._~-' | head -c 48 > /mnt/user/appdata/secrets/dawarich_redis_password.txt
|
||||||
|
openssl rand -hex 64 > /mnt/user/appdata/secrets/dawarich_secret_key_base.txt
|
||||||
|
openssl rand -base64 48 > /mnt/user/appdata/secrets/dawarich_metrics_password.txt
|
||||||
|
openssl rand -base64 48 > /mnt/user/appdata/secrets/dawarich_grafana_ro_password.txt
|
||||||
|
chmod 600 /mnt/user/appdata/secrets/dawarich_*.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Bind-Volume-Zielpfade vor dem ersten Deploy anlegen:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
install -d -m 750 \
|
||||||
|
/mnt/user/appdata/dawarich/postgres17 \
|
||||||
|
/mnt/user/appdata/dawarich/redis \
|
||||||
|
/mnt/user/appdata/dawarich/shared \
|
||||||
|
/mnt/user/appdata/dawarich/public \
|
||||||
|
/mnt/user/appdata/dawarich/watched \
|
||||||
|
/mnt/user/appdata/dawarich/storage
|
||||||
|
```
|
||||||
|
|
||||||
|
5. In Komodo als Compose-Stack deployen. `frontend_net` und `backend_net` muessen bereits existieren.
|
||||||
|
6. Ersten Login in Dawarich durchfuehren und den API-Key im Account-Bereich erzeugen.
|
||||||
|
7. Home Assistant `homeassistant-dawarich.example.yaml` in das Smart-Home-Fachrepo uebernehmen und `device_tracker.your_phone` ersetzen.
|
||||||
|
|
||||||
|
## Traefik und Authelia
|
||||||
|
|
||||||
|
Die UI liegt auf `https://dawarich.kaleschke.info` und nutzt `authelia@file,secure-headers@file`.
|
||||||
|
|
||||||
|
Die Tracking-API-Routen fuer OwnTracks, Overland und Traccar sind separat und priorisiert ohne Authelia geroutet, weil diese Clients per Dawarich-API-Key authentifizieren und keine Browser-ForwardAuth-Challenge verarbeiten koennen.
|
||||||
|
|
||||||
|
## Prometheus
|
||||||
|
|
||||||
|
`prometheus-scrape.snippet.yml` ist die dienstnahe Referenz. Produktiv ist der Job bereits in `monitoring/prometheus/prometheus.yml` eingetragen.
|
||||||
|
|
||||||
|
Der Monitoring-Stack ist dafuer bereits vorbereitet:
|
||||||
|
|
||||||
|
- `prometheus` haengt an `backend_net`, damit `dawarich_app` erreichbar ist.
|
||||||
|
- `/mnt/user/appdata/secrets/dawarich_metrics_password.txt` ist als Docker Secret eingebunden.
|
||||||
|
|
||||||
|
Nicht `dawarich_app:9394` scrapen: das ist nach aktueller Dawarich-Doku veraltet. Der Web-Service aggregiert App- und Sidekiq-Metriken unter `dawarich_app:3000/metrics`.
|
||||||
|
|
||||||
|
## Grafana
|
||||||
|
|
||||||
|
Der Read-only-User `dawarich_grafana_ro` wird beim ersten DB-Init durch `postgres/initdb/20-grafana-readonly.sh` angelegt.
|
||||||
|
|
||||||
|
Bei einer bereits initialisierten DB das Script einmal manuell im DB-Container ausfuehren:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker exec dawarich_db /docker-entrypoint-initdb.d/20-grafana-readonly.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Die produktive Provisionierung ist bereits in den vorhandenen Monitoring-Stack integriert:
|
||||||
|
|
||||||
|
- Datasource: `monitoring/grafana/provisioning/datasources/dawarich.yml`
|
||||||
|
- Dashboard: `monitoring/grafana/dashboards/dawarich.json`
|
||||||
|
- Grafana haengt an `backend_net`, damit `dawarich_db:5432` erreichbar ist.
|
||||||
|
- `DAWARICH_GRAFANA_RO_PASSWORD` wird beim Grafana-Start aus `/mnt/user/appdata/secrets/dawarich_grafana_ro_password.txt` exportiert.
|
||||||
|
|
||||||
|
## Home Assistant
|
||||||
|
|
||||||
|
Dawarich akzeptiert OwnTracks-kompatible Location-Punkte per:
|
||||||
|
|
||||||
|
```text
|
||||||
|
https://dawarich.kaleschke.info/api/v1/owntracks/points?api_key=<dawarich-api-key>
|
||||||
|
```
|
||||||
|
|
||||||
|
`homeassistant-dawarich.example.yaml` enthaelt:
|
||||||
|
|
||||||
|
- `rest_command.dawarich_push_owntracks`
|
||||||
|
- Automation fuer `device_tracker`-State-Changes
|
||||||
|
- API-Key aus HA `secrets.yaml` als `dawarich_api_key`
|
||||||
|
|
||||||
|
Alternativ existiert eine HACS-Integration `dawarich-home-assistant`; die YAML-Variante hier bleibt absichtlich transparent und GitOps-lesbar.
|
||||||
|
|
||||||
|
## Backup mit Borg
|
||||||
|
|
||||||
|
Borg-relevante Daten liegen unter:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/mnt/user/appdata/dawarich/postgres17
|
||||||
|
/mnt/user/appdata/dawarich/redis
|
||||||
|
/mnt/user/appdata/dawarich/shared
|
||||||
|
/mnt/user/appdata/dawarich/public
|
||||||
|
/mnt/user/appdata/dawarich/watched
|
||||||
|
/mnt/user/appdata/dawarich/storage
|
||||||
|
/mnt/user/appdata/secrets/dawarich_*.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
Primaerer Restore-Weg fuer die DB sollte ein logischer Dump plus Appdaten sein. Raw-Postgres-Verzeichnisse sind nur fuer gleiches Major/PostGIS-Image und sauberen Shutdown geeignet.
|
||||||
|
|
||||||
|
Empfohlener Dump vor Borg:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker exec dawarich_db pg_dump -U dawarich -d dawarich_production -Fc > /mnt/user/backups/borg/dumps/latest/dawarich.dump
|
||||||
|
```
|
||||||
|
|
||||||
|
## Updates
|
||||||
|
|
||||||
|
- Kein `latest` verwenden.
|
||||||
|
- Vor jedem Update Release Notes lesen, besonders bei Dawarich und PostGIS.
|
||||||
|
- Dawarich App und Sidekiq muessen immer dasselbe Image-Tag nutzen.
|
||||||
|
- PostGIS-Major-/Minor-Wechsel getrennt planen und vorher Dump plus Restore-Probe erstellen.
|
||||||
|
- Image-Digests nach Review bewusst aktualisieren.
|
||||||
|
|
||||||
|
## Rollback
|
||||||
|
|
||||||
|
1. Komodo Stack stoppen.
|
||||||
|
2. Vorherigen Git-Commit mit altem Image-Tag/Digest deployen.
|
||||||
|
3. Falls nur App-Code gewechselt wurde: Stack starten und Healthchecks pruefen.
|
||||||
|
4. Falls DB-Migrationen gelaufen sind: DB aus `dawarich.dump` in einen frischen PostGIS-17-Container restoren; kein blindes Zurueckkopieren eines Live-Postgres-Verzeichnisses.
|
||||||
|
5. Dawarich UI, `/api/v1/health`, Prometheus-Scrape und HA-Push testen.
|
||||||
@@ -0,0 +1,271 @@
|
|||||||
|
name: dawarich
|
||||||
|
|
||||||
|
x-dawarich-image: &dawarich_image freikin/dawarich:1.8.1@sha256:7c70f2169e848ed77ae1cec01dd10ec4a73a70a785d4e4d248db1735c0bc25ed
|
||||||
|
|
||||||
|
services:
|
||||||
|
dawarich_db:
|
||||||
|
image: postgis/postgis:17-3.5-alpine@sha256:fc07e7a034e013d50ada575673b798ca6277e000b8364e39e217f612d94bd9a5
|
||||||
|
container_name: dawarich_db
|
||||||
|
restart: unless-stopped
|
||||||
|
shm_size: 1G
|
||||||
|
environment:
|
||||||
|
TZ: ${TZ}
|
||||||
|
POSTGRES_USER: ${POSTGRES_USER}
|
||||||
|
POSTGRES_DB: ${POSTGRES_DB}
|
||||||
|
POSTGRES_PASSWORD_FILE: /run/secrets/dawarich_postgres_password
|
||||||
|
GRAFANA_DB_USER: ${GRAFANA_DB_USER}
|
||||||
|
PGDATA: /var/lib/postgresql/data
|
||||||
|
volumes:
|
||||||
|
- dawarich_db_data:/var/lib/postgresql/data
|
||||||
|
- dawarich_shared:/var/shared
|
||||||
|
- ./postgres/initdb:/docker-entrypoint-initdb.d:ro
|
||||||
|
networks:
|
||||||
|
- backend_net
|
||||||
|
secrets:
|
||||||
|
- dawarich_postgres_password
|
||||||
|
- dawarich_grafana_ro_password
|
||||||
|
expose:
|
||||||
|
- "5432"
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "pg_isready -U \"$${POSTGRES_USER}\" -d \"$${POSTGRES_DB}\""]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 5
|
||||||
|
start_period: 30s
|
||||||
|
security_opt:
|
||||||
|
- no-new-privileges:true
|
||||||
|
|
||||||
|
dawarich_redis:
|
||||||
|
image: redis:7-alpine@sha256:6ab0b6e7381779332f97b8ca76193e45b0756f38d4c0dcda72dbb3c32061ab99
|
||||||
|
container_name: dawarich_redis
|
||||||
|
restart: unless-stopped
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -lc
|
||||||
|
- |
|
||||||
|
exec redis-server \
|
||||||
|
--save 900 1 \
|
||||||
|
--save 300 10 \
|
||||||
|
--appendonly no \
|
||||||
|
--requirepass "$$(cat /run/secrets/dawarich_redis_password)"
|
||||||
|
volumes:
|
||||||
|
- dawarich_redis_data:/data
|
||||||
|
networks:
|
||||||
|
- backend_net
|
||||||
|
secrets:
|
||||||
|
- dawarich_redis_password
|
||||||
|
expose:
|
||||||
|
- "6379"
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "redis-cli -a \"$$(cat /run/secrets/dawarich_redis_password)\" --raw incr ping >/dev/null"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 5
|
||||||
|
start_period: 30s
|
||||||
|
security_opt:
|
||||||
|
- no-new-privileges:true
|
||||||
|
|
||||||
|
dawarich_app:
|
||||||
|
image: *dawarich_image
|
||||||
|
container_name: dawarich_app
|
||||||
|
restart: unless-stopped
|
||||||
|
stdin_open: true
|
||||||
|
tty: true
|
||||||
|
entrypoint:
|
||||||
|
- /bin/sh
|
||||||
|
- -lc
|
||||||
|
command:
|
||||||
|
- |
|
||||||
|
export DATABASE_PASSWORD="$$(cat /run/secrets/dawarich_postgres_password)"
|
||||||
|
export REDIS_URL="redis://:$$(cat /run/secrets/dawarich_redis_password)@dawarich_redis:6379/0"
|
||||||
|
export SECRET_KEY_BASE="$$(cat /run/secrets/dawarich_secret_key_base)"
|
||||||
|
export METRICS_PASSWORD="$$(cat /run/secrets/dawarich_metrics_password)"
|
||||||
|
exec web-entrypoint.sh bin/rails server -p 3000 -b ::
|
||||||
|
environment:
|
||||||
|
TZ: ${TZ}
|
||||||
|
RAILS_ENV: production
|
||||||
|
DATABASE_HOST: dawarich_db
|
||||||
|
DATABASE_PORT: "5432"
|
||||||
|
DATABASE_USERNAME: ${POSTGRES_USER}
|
||||||
|
DATABASE_NAME: ${POSTGRES_DB}
|
||||||
|
APPLICATION_HOSTS: ${APPLICATION_HOSTS}
|
||||||
|
APPLICATION_PROTOCOL: https
|
||||||
|
TIME_ZONE: ${TZ}
|
||||||
|
SELF_HOSTED: "true"
|
||||||
|
STORE_GEODATA: "true"
|
||||||
|
RAILS_LOG_TO_STDOUT: "true"
|
||||||
|
PROMETHEUS_EXPORTER_ENABLED: "true"
|
||||||
|
METRICS_USERNAME: ${METRICS_USERNAME}
|
||||||
|
SIDEKIQ_METRICS_URL: http://dawarich_sidekiq:9394/metrics
|
||||||
|
BACKGROUND_PROCESSING_CONCURRENCY: ${BACKGROUND_PROCESSING_CONCURRENCY}
|
||||||
|
RAILS_MAX_THREADS: ${RAILS_MAX_THREADS}
|
||||||
|
volumes:
|
||||||
|
- dawarich_public:/var/app/public
|
||||||
|
- dawarich_watched:/var/app/tmp/imports/watched
|
||||||
|
- dawarich_storage:/var/app/storage
|
||||||
|
- dawarich_db_data:/dawarich_db_data:ro
|
||||||
|
networks:
|
||||||
|
- frontend_net
|
||||||
|
- backend_net
|
||||||
|
secrets:
|
||||||
|
- dawarich_postgres_password
|
||||||
|
- dawarich_redis_password
|
||||||
|
- dawarich_secret_key_base
|
||||||
|
- dawarich_metrics_password
|
||||||
|
expose:
|
||||||
|
- "3000"
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "wget -qO - http://127.0.0.1:3000/api/v1/health | grep -q '\"status\"[[:space:]]*:[[:space:]]*\"ok\"'"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 30
|
||||||
|
start_period: 30s
|
||||||
|
depends_on:
|
||||||
|
dawarich_db:
|
||||||
|
condition: service_healthy
|
||||||
|
dawarich_redis:
|
||||||
|
condition: service_healthy
|
||||||
|
security_opt:
|
||||||
|
- no-new-privileges:true
|
||||||
|
labels:
|
||||||
|
- traefik.enable=true
|
||||||
|
- traefik.docker.network=frontend_net
|
||||||
|
|
||||||
|
# Public API-key endpoints for mobile apps and Home Assistant pushes.
|
||||||
|
- traefik.http.routers.dawarich-api.rule=Host(`${DAWARICH_HOST}`) && (Path(`/api/v1/owntracks/points`) || Path(`/api/v1/overland/batches`) || Path(`/api/v1/traccar/points`))
|
||||||
|
- traefik.http.routers.dawarich-api.entrypoints=websecure
|
||||||
|
- traefik.http.routers.dawarich-api.tls=true
|
||||||
|
- traefik.http.routers.dawarich-api.tls.certresolver=le
|
||||||
|
- traefik.http.routers.dawarich-api.priority=100
|
||||||
|
- traefik.http.routers.dawarich-api.middlewares=secure-headers@file
|
||||||
|
- traefik.http.routers.dawarich-api.service=dawarich
|
||||||
|
|
||||||
|
# UI and all other routes require Authelia ForwardAuth.
|
||||||
|
- traefik.http.routers.dawarich.rule=Host(`${DAWARICH_HOST}`)
|
||||||
|
- traefik.http.routers.dawarich.entrypoints=websecure
|
||||||
|
- traefik.http.routers.dawarich.tls=true
|
||||||
|
- traefik.http.routers.dawarich.tls.certresolver=le
|
||||||
|
- traefik.http.routers.dawarich.priority=10
|
||||||
|
- traefik.http.routers.dawarich.middlewares=authelia@file,secure-headers@file
|
||||||
|
- traefik.http.routers.dawarich.service=dawarich
|
||||||
|
- traefik.http.services.dawarich.loadbalancer.server.port=3000
|
||||||
|
|
||||||
|
dawarich_sidekiq:
|
||||||
|
image: *dawarich_image
|
||||||
|
container_name: dawarich_sidekiq
|
||||||
|
restart: unless-stopped
|
||||||
|
stdin_open: true
|
||||||
|
tty: true
|
||||||
|
entrypoint:
|
||||||
|
- /bin/sh
|
||||||
|
- -lc
|
||||||
|
command:
|
||||||
|
- |
|
||||||
|
export DATABASE_PASSWORD="$$(cat /run/secrets/dawarich_postgres_password)"
|
||||||
|
export REDIS_URL="redis://:$$(cat /run/secrets/dawarich_redis_password)@dawarich_redis:6379/0"
|
||||||
|
export SECRET_KEY_BASE="$$(cat /run/secrets/dawarich_secret_key_base)"
|
||||||
|
export METRICS_PASSWORD="$$(cat /run/secrets/dawarich_metrics_password)"
|
||||||
|
exec sidekiq-entrypoint.sh sidekiq
|
||||||
|
environment:
|
||||||
|
TZ: ${TZ}
|
||||||
|
RAILS_ENV: production
|
||||||
|
DATABASE_HOST: dawarich_db
|
||||||
|
DATABASE_PORT: "5432"
|
||||||
|
DATABASE_USERNAME: ${POSTGRES_USER}
|
||||||
|
DATABASE_NAME: ${POSTGRES_DB}
|
||||||
|
APPLICATION_HOSTS: ${APPLICATION_HOSTS}
|
||||||
|
APPLICATION_PROTOCOL: https
|
||||||
|
TIME_ZONE: ${TZ}
|
||||||
|
SELF_HOSTED: "true"
|
||||||
|
STORE_GEODATA: "true"
|
||||||
|
RAILS_LOG_TO_STDOUT: "true"
|
||||||
|
PROMETHEUS_EXPORTER_ENABLED: "true"
|
||||||
|
PROMETHEUS_EXPORTER_PORT: "9394"
|
||||||
|
METRICS_USERNAME: ${METRICS_USERNAME}
|
||||||
|
BACKGROUND_PROCESSING_CONCURRENCY: ${BACKGROUND_PROCESSING_CONCURRENCY}
|
||||||
|
RAILS_MAX_THREADS: ${RAILS_MAX_THREADS}
|
||||||
|
volumes:
|
||||||
|
- dawarich_public:/var/app/public
|
||||||
|
- dawarich_watched:/var/app/tmp/imports/watched
|
||||||
|
- dawarich_storage:/var/app/storage
|
||||||
|
networks:
|
||||||
|
- frontend_net
|
||||||
|
- backend_net
|
||||||
|
secrets:
|
||||||
|
- dawarich_postgres_password
|
||||||
|
- dawarich_redis_password
|
||||||
|
- dawarich_secret_key_base
|
||||||
|
- dawarich_metrics_password
|
||||||
|
expose:
|
||||||
|
- "9394"
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "pgrep -f sidekiq >/dev/null"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 30
|
||||||
|
start_period: 30s
|
||||||
|
depends_on:
|
||||||
|
dawarich_db:
|
||||||
|
condition: service_healthy
|
||||||
|
dawarich_redis:
|
||||||
|
condition: service_healthy
|
||||||
|
dawarich_app:
|
||||||
|
condition: service_healthy
|
||||||
|
security_opt:
|
||||||
|
- no-new-privileges:true
|
||||||
|
|
||||||
|
networks:
|
||||||
|
frontend_net:
|
||||||
|
external: true
|
||||||
|
backend_net:
|
||||||
|
external: true
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
dawarich_db_data:
|
||||||
|
driver: local
|
||||||
|
driver_opts:
|
||||||
|
type: none
|
||||||
|
o: bind
|
||||||
|
device: /mnt/user/appdata/dawarich/postgres17
|
||||||
|
dawarich_redis_data:
|
||||||
|
driver: local
|
||||||
|
driver_opts:
|
||||||
|
type: none
|
||||||
|
o: bind
|
||||||
|
device: /mnt/user/appdata/dawarich/redis
|
||||||
|
dawarich_shared:
|
||||||
|
driver: local
|
||||||
|
driver_opts:
|
||||||
|
type: none
|
||||||
|
o: bind
|
||||||
|
device: /mnt/user/appdata/dawarich/shared
|
||||||
|
dawarich_public:
|
||||||
|
driver: local
|
||||||
|
driver_opts:
|
||||||
|
type: none
|
||||||
|
o: bind
|
||||||
|
device: /mnt/user/appdata/dawarich/public
|
||||||
|
dawarich_watched:
|
||||||
|
driver: local
|
||||||
|
driver_opts:
|
||||||
|
type: none
|
||||||
|
o: bind
|
||||||
|
device: /mnt/user/appdata/dawarich/watched
|
||||||
|
dawarich_storage:
|
||||||
|
driver: local
|
||||||
|
driver_opts:
|
||||||
|
type: none
|
||||||
|
o: bind
|
||||||
|
device: /mnt/user/appdata/dawarich/storage
|
||||||
|
|
||||||
|
secrets:
|
||||||
|
dawarich_postgres_password:
|
||||||
|
file: /mnt/user/appdata/secrets/dawarich_postgres_password.txt
|
||||||
|
dawarich_redis_password:
|
||||||
|
file: /mnt/user/appdata/secrets/dawarich_redis_password.txt
|
||||||
|
dawarich_secret_key_base:
|
||||||
|
file: /mnt/user/appdata/secrets/dawarich_secret_key_base.txt
|
||||||
|
dawarich_metrics_password:
|
||||||
|
file: /mnt/user/appdata/secrets/dawarich_metrics_password.txt
|
||||||
|
dawarich_grafana_ro_password:
|
||||||
|
file: /mnt/user/appdata/secrets/dawarich_grafana_ro_password.txt
|
||||||
@@ -0,0 +1,355 @@
|
|||||||
|
{
|
||||||
|
"annotations": {
|
||||||
|
"list": [
|
||||||
|
{
|
||||||
|
"builtIn": 1,
|
||||||
|
"datasource": {
|
||||||
|
"type": "grafana",
|
||||||
|
"uid": "-- Grafana --"
|
||||||
|
},
|
||||||
|
"enable": true,
|
||||||
|
"hide": true,
|
||||||
|
"iconColor": "rgba(0, 211, 255, 1)",
|
||||||
|
"name": "Annotations & Alerts",
|
||||||
|
"type": "dashboard"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"editable": false,
|
||||||
|
"fiscalYearStartMonth": 0,
|
||||||
|
"graphTooltip": 0,
|
||||||
|
"id": null,
|
||||||
|
"links": [],
|
||||||
|
"panels": [
|
||||||
|
{
|
||||||
|
"datasource": {
|
||||||
|
"type": "postgres",
|
||||||
|
"uid": "dawarich-postgres"
|
||||||
|
},
|
||||||
|
"fieldConfig": {
|
||||||
|
"defaults": {
|
||||||
|
"custom": {
|
||||||
|
"hideFrom": {
|
||||||
|
"legend": false,
|
||||||
|
"tooltip": false,
|
||||||
|
"viz": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"mappings": [],
|
||||||
|
"thresholds": {
|
||||||
|
"mode": "absolute",
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"color": "green",
|
||||||
|
"value": null
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"unit": "none"
|
||||||
|
},
|
||||||
|
"overrides": []
|
||||||
|
},
|
||||||
|
"gridPos": {
|
||||||
|
"h": 16,
|
||||||
|
"w": 16,
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
"id": 1,
|
||||||
|
"options": {
|
||||||
|
"basemap": {
|
||||||
|
"config": {},
|
||||||
|
"name": "Layer 0",
|
||||||
|
"type": "default"
|
||||||
|
},
|
||||||
|
"controls": {
|
||||||
|
"mouseWheelZoom": true,
|
||||||
|
"showAttribution": true,
|
||||||
|
"showDebug": false,
|
||||||
|
"showMeasure": false,
|
||||||
|
"showScale": true,
|
||||||
|
"showZoom": true
|
||||||
|
},
|
||||||
|
"layers": [
|
||||||
|
{
|
||||||
|
"config": {
|
||||||
|
"showLegend": true,
|
||||||
|
"style": {
|
||||||
|
"color": {
|
||||||
|
"fixed": "dark-green"
|
||||||
|
},
|
||||||
|
"opacity": 0.55,
|
||||||
|
"rotation": {
|
||||||
|
"fixed": 0,
|
||||||
|
"max": 360,
|
||||||
|
"min": -360,
|
||||||
|
"mode": "mod"
|
||||||
|
},
|
||||||
|
"size": {
|
||||||
|
"fixed": 4,
|
||||||
|
"max": 15,
|
||||||
|
"min": 2
|
||||||
|
},
|
||||||
|
"symbol": {
|
||||||
|
"fixed": "img/icons/marker/circle.svg",
|
||||||
|
"mode": "fixed"
|
||||||
|
},
|
||||||
|
"textConfig": {
|
||||||
|
"fontSize": 12,
|
||||||
|
"offsetX": 0,
|
||||||
|
"offsetY": 0,
|
||||||
|
"textAlign": "center",
|
||||||
|
"textBaseline": "middle"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"location": {
|
||||||
|
"latitude": "latitude",
|
||||||
|
"longitude": "longitude",
|
||||||
|
"mode": "coords"
|
||||||
|
},
|
||||||
|
"name": "Location points",
|
||||||
|
"tooltip": true,
|
||||||
|
"type": "markers"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tooltip": {
|
||||||
|
"mode": "details"
|
||||||
|
},
|
||||||
|
"view": {
|
||||||
|
"allLayers": true,
|
||||||
|
"id": "fit",
|
||||||
|
"lat": 51,
|
||||||
|
"lon": 10,
|
||||||
|
"zoom": 5
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pluginVersion": "13.0.2",
|
||||||
|
"targets": [
|
||||||
|
{
|
||||||
|
"datasource": {
|
||||||
|
"type": "postgres",
|
||||||
|
"uid": "dawarich-postgres"
|
||||||
|
},
|
||||||
|
"editorMode": "code",
|
||||||
|
"format": "table",
|
||||||
|
"rawQuery": true,
|
||||||
|
"rawSql": "SELECT\n to_timestamp(timestamp) AS \"time\",\n ST_Y(lonlat::geometry) AS latitude,\n ST_X(lonlat::geometry) AS longitude,\n accuracy,\n tracker_id\nFROM points\nWHERE $__unixEpochFilter(timestamp)\n AND lonlat IS NOT NULL\nORDER BY timestamp DESC\nLIMIT 20000;",
|
||||||
|
"refId": "A"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"title": "Location Points",
|
||||||
|
"type": "geomap"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"datasource": {
|
||||||
|
"type": "postgres",
|
||||||
|
"uid": "dawarich-postgres"
|
||||||
|
},
|
||||||
|
"fieldConfig": {
|
||||||
|
"defaults": {
|
||||||
|
"color": {
|
||||||
|
"mode": "palette-classic"
|
||||||
|
},
|
||||||
|
"custom": {
|
||||||
|
"axisBorderShow": false,
|
||||||
|
"axisCenteredZero": false,
|
||||||
|
"axisColorMode": "text",
|
||||||
|
"axisLabel": "",
|
||||||
|
"axisPlacement": "auto",
|
||||||
|
"barAlignment": 0,
|
||||||
|
"drawStyle": "bars",
|
||||||
|
"fillOpacity": 70,
|
||||||
|
"gradientMode": "none",
|
||||||
|
"hideFrom": {
|
||||||
|
"legend": false,
|
||||||
|
"tooltip": false,
|
||||||
|
"viz": false
|
||||||
|
},
|
||||||
|
"insertNulls": false,
|
||||||
|
"lineInterpolation": "linear",
|
||||||
|
"lineWidth": 1,
|
||||||
|
"pointSize": 5,
|
||||||
|
"scaleDistribution": {
|
||||||
|
"type": "linear"
|
||||||
|
},
|
||||||
|
"showPoints": "never",
|
||||||
|
"spanNulls": false,
|
||||||
|
"stacking": {
|
||||||
|
"group": "A",
|
||||||
|
"mode": "none"
|
||||||
|
},
|
||||||
|
"thresholdsStyle": {
|
||||||
|
"mode": "off"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"mappings": [],
|
||||||
|
"thresholds": {
|
||||||
|
"mode": "absolute",
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"color": "green",
|
||||||
|
"value": null
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"unit": "km"
|
||||||
|
},
|
||||||
|
"overrides": []
|
||||||
|
},
|
||||||
|
"gridPos": {
|
||||||
|
"h": 8,
|
||||||
|
"w": 8,
|
||||||
|
"x": 16,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
"id": 2,
|
||||||
|
"options": {
|
||||||
|
"legend": {
|
||||||
|
"calcs": [
|
||||||
|
"sum"
|
||||||
|
],
|
||||||
|
"displayMode": "list",
|
||||||
|
"placement": "bottom",
|
||||||
|
"showLegend": true
|
||||||
|
},
|
||||||
|
"tooltip": {
|
||||||
|
"hideZeros": false,
|
||||||
|
"mode": "single",
|
||||||
|
"sort": "none"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pluginVersion": "13.0.2",
|
||||||
|
"targets": [
|
||||||
|
{
|
||||||
|
"datasource": {
|
||||||
|
"type": "postgres",
|
||||||
|
"uid": "dawarich-postgres"
|
||||||
|
},
|
||||||
|
"editorMode": "code",
|
||||||
|
"format": "time_series",
|
||||||
|
"rawQuery": true,
|
||||||
|
"rawSql": "SELECT\n make_date(year, month, 1)::timestamp AS \"time\",\n round((distance::numeric / 1000.0), 2) AS \"km\"\nFROM stats\nWHERE make_date(year, month, 1)::timestamp BETWEEN $__timeFrom() AND $__timeTo()\nORDER BY 1;",
|
||||||
|
"refId": "A"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"title": "Kilometers per Month",
|
||||||
|
"type": "timeseries"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"datasource": {
|
||||||
|
"type": "postgres",
|
||||||
|
"uid": "dawarich-postgres"
|
||||||
|
},
|
||||||
|
"fieldConfig": {
|
||||||
|
"defaults": {
|
||||||
|
"color": {
|
||||||
|
"mode": "palette-classic"
|
||||||
|
},
|
||||||
|
"custom": {
|
||||||
|
"axisBorderShow": false,
|
||||||
|
"axisCenteredZero": false,
|
||||||
|
"axisColorMode": "text",
|
||||||
|
"axisLabel": "",
|
||||||
|
"axisPlacement": "auto",
|
||||||
|
"barAlignment": 0,
|
||||||
|
"drawStyle": "bars",
|
||||||
|
"fillOpacity": 70,
|
||||||
|
"gradientMode": "none",
|
||||||
|
"hideFrom": {
|
||||||
|
"legend": false,
|
||||||
|
"tooltip": false,
|
||||||
|
"viz": false
|
||||||
|
},
|
||||||
|
"insertNulls": false,
|
||||||
|
"lineInterpolation": "linear",
|
||||||
|
"lineWidth": 1,
|
||||||
|
"pointSize": 5,
|
||||||
|
"scaleDistribution": {
|
||||||
|
"type": "linear"
|
||||||
|
},
|
||||||
|
"showPoints": "never",
|
||||||
|
"spanNulls": false,
|
||||||
|
"stacking": {
|
||||||
|
"group": "A",
|
||||||
|
"mode": "none"
|
||||||
|
},
|
||||||
|
"thresholdsStyle": {
|
||||||
|
"mode": "off"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"mappings": [],
|
||||||
|
"thresholds": {
|
||||||
|
"mode": "absolute",
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"color": "green",
|
||||||
|
"value": null
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"unit": "short"
|
||||||
|
},
|
||||||
|
"overrides": []
|
||||||
|
},
|
||||||
|
"gridPos": {
|
||||||
|
"h": 8,
|
||||||
|
"w": 8,
|
||||||
|
"x": 16,
|
||||||
|
"y": 8
|
||||||
|
},
|
||||||
|
"id": 3,
|
||||||
|
"options": {
|
||||||
|
"legend": {
|
||||||
|
"calcs": [
|
||||||
|
"sum"
|
||||||
|
],
|
||||||
|
"displayMode": "list",
|
||||||
|
"placement": "bottom",
|
||||||
|
"showLegend": true
|
||||||
|
},
|
||||||
|
"tooltip": {
|
||||||
|
"hideZeros": false,
|
||||||
|
"mode": "single",
|
||||||
|
"sort": "none"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pluginVersion": "13.0.2",
|
||||||
|
"targets": [
|
||||||
|
{
|
||||||
|
"datasource": {
|
||||||
|
"type": "postgres",
|
||||||
|
"uid": "dawarich-postgres"
|
||||||
|
},
|
||||||
|
"editorMode": "code",
|
||||||
|
"format": "time_series",
|
||||||
|
"rawQuery": true,
|
||||||
|
"rawSql": "SELECT\n date_trunc('day', to_timestamp(timestamp)) AS \"time\",\n count(*) AS \"points\"\nFROM points\nWHERE $__unixEpochFilter(timestamp)\nGROUP BY 1\nORDER BY 1;",
|
||||||
|
"refId": "A"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"title": "Points per Day",
|
||||||
|
"type": "timeseries"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"preload": false,
|
||||||
|
"refresh": "5m",
|
||||||
|
"schemaVersion": 41,
|
||||||
|
"tags": [
|
||||||
|
"dawarich",
|
||||||
|
"location"
|
||||||
|
],
|
||||||
|
"templating": {
|
||||||
|
"list": []
|
||||||
|
},
|
||||||
|
"time": {
|
||||||
|
"from": "now-30d",
|
||||||
|
"to": "now"
|
||||||
|
},
|
||||||
|
"timepicker": {},
|
||||||
|
"timezone": "browser",
|
||||||
|
"title": "Dawarich",
|
||||||
|
"uid": "dawarich",
|
||||||
|
"version": 1,
|
||||||
|
"weekStart": ""
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
apiVersion: 1
|
||||||
|
|
||||||
|
datasources:
|
||||||
|
- name: Dawarich PostgreSQL
|
||||||
|
uid: dawarich-postgres
|
||||||
|
type: postgres
|
||||||
|
access: proxy
|
||||||
|
url: dawarich_db:5432
|
||||||
|
database: dawarich_production
|
||||||
|
user: dawarich_grafana_ro
|
||||||
|
editable: false
|
||||||
|
jsonData:
|
||||||
|
sslmode: disable
|
||||||
|
postgresVersion: 1700
|
||||||
|
timescaledb: false
|
||||||
|
secureJsonData:
|
||||||
|
password: $DAWARICH_GRAFANA_RO_PASSWORD
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
# Add `dawarich_api_key` to Home Assistant `secrets.yaml`.
|
||||||
|
# The endpoint is the current OwnTracks-compatible Dawarich endpoint:
|
||||||
|
# https://<host>/api/v1/owntracks/points?api_key=<api-key>
|
||||||
|
|
||||||
|
rest_command:
|
||||||
|
dawarich_push_owntracks:
|
||||||
|
url: "https://dawarich.kaleschke.info/api/v1/owntracks/points?api_key={{ api_key }}"
|
||||||
|
method: POST
|
||||||
|
content_type: "application/json"
|
||||||
|
payload: >-
|
||||||
|
{
|
||||||
|
"_type": "location",
|
||||||
|
"lat": {{ latitude }},
|
||||||
|
"lon": {{ longitude }},
|
||||||
|
"tst": {{ timestamp }},
|
||||||
|
"acc": {{ accuracy | default(0) }},
|
||||||
|
"alt": {{ altitude | default(0) }},
|
||||||
|
"batt": {{ battery | default(0) }},
|
||||||
|
"tid": "{{ tracker_id[:2] }}"
|
||||||
|
}
|
||||||
|
|
||||||
|
automation:
|
||||||
|
- id: dawarich_push_device_tracker_location
|
||||||
|
alias: Dawarich - push device tracker location
|
||||||
|
mode: queued
|
||||||
|
max: 20
|
||||||
|
trigger:
|
||||||
|
- platform: state
|
||||||
|
entity_id:
|
||||||
|
- device_tracker.your_phone
|
||||||
|
condition:
|
||||||
|
- condition: template
|
||||||
|
value_template: >-
|
||||||
|
{{ trigger.to_state is not none
|
||||||
|
and state_attr(trigger.entity_id, 'latitude') is number
|
||||||
|
and state_attr(trigger.entity_id, 'longitude') is number }}
|
||||||
|
action:
|
||||||
|
- service: rest_command.dawarich_push_owntracks
|
||||||
|
data:
|
||||||
|
api_key: !secret dawarich_api_key
|
||||||
|
tracker_id: "{{ trigger.entity_id.split('.')[1] }}"
|
||||||
|
latitude: "{{ state_attr(trigger.entity_id, 'latitude') }}"
|
||||||
|
longitude: "{{ state_attr(trigger.entity_id, 'longitude') }}"
|
||||||
|
accuracy: "{{ state_attr(trigger.entity_id, 'gps_accuracy') | default(0, true) }}"
|
||||||
|
altitude: "{{ state_attr(trigger.entity_id, 'altitude') | default(0, true) }}"
|
||||||
|
battery: "{{ state_attr(trigger.entity_id, 'battery_level') | default(0, true) }}"
|
||||||
|
timestamp: "{{ as_timestamp(trigger.to_state.last_updated) | int }}"
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
GRAFANA_USER="${GRAFANA_DB_USER:-dawarich_grafana_ro}"
|
||||||
|
GRAFANA_PASSWORD="$(cat /run/secrets/dawarich_grafana_ro_password)"
|
||||||
|
|
||||||
|
sql_ident() {
|
||||||
|
printf '"%s"' "$(printf '%s' "$1" | sed 's/"/""/g')"
|
||||||
|
}
|
||||||
|
|
||||||
|
sql_literal() {
|
||||||
|
printf "'%s'" "$(printf '%s' "$1" | sed "s/'/''/g")"
|
||||||
|
}
|
||||||
|
|
||||||
|
DB_IDENT="$(sql_ident "$POSTGRES_DB")"
|
||||||
|
USER_IDENT="$(sql_ident "$GRAFANA_USER")"
|
||||||
|
USER_LITERAL="$(sql_literal "$GRAFANA_USER")"
|
||||||
|
PASSWORD_LITERAL="$(sql_literal "$GRAFANA_PASSWORD")"
|
||||||
|
|
||||||
|
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<EOSQL
|
||||||
|
DO \$\$
|
||||||
|
BEGIN
|
||||||
|
IF NOT EXISTS (SELECT 1 FROM pg_catalog.pg_roles WHERE rolname = ${USER_LITERAL}) THEN
|
||||||
|
EXECUTE 'CREATE ROLE ${USER_IDENT} LOGIN PASSWORD ${PASSWORD_LITERAL}';
|
||||||
|
ELSE
|
||||||
|
EXECUTE 'ALTER ROLE ${USER_IDENT} WITH LOGIN PASSWORD ${PASSWORD_LITERAL}';
|
||||||
|
END IF;
|
||||||
|
END
|
||||||
|
\$\$;
|
||||||
|
|
||||||
|
GRANT CONNECT ON DATABASE ${DB_IDENT} TO ${USER_IDENT};
|
||||||
|
GRANT USAGE ON SCHEMA public TO ${USER_IDENT};
|
||||||
|
GRANT SELECT ON ALL TABLES IN SCHEMA public TO ${USER_IDENT};
|
||||||
|
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO ${USER_IDENT};
|
||||||
|
EOSQL
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
# Dawarich 1.8.1 serves the Prometheus endpoint on the web service at
|
||||||
|
# /metrics. Port 9394 is the internal Sidekiq metrics endpoint consumed by
|
||||||
|
# dawarich_app via SIDEKIQ_METRICS_URL.
|
||||||
|
#
|
||||||
|
# Prerequisites in monitoring/docker-compose.yml:
|
||||||
|
# - attach service `prometheus` to external `backend_net`
|
||||||
|
# - mount Docker secret/file `/mnt/user/appdata/secrets/dawarich_metrics_password.txt`
|
||||||
|
# into the Prometheus container at `/run/secrets/dawarich_metrics_password`
|
||||||
|
|
||||||
|
- job_name: dawarich
|
||||||
|
metrics_path: /metrics
|
||||||
|
scheme: http
|
||||||
|
basic_auth:
|
||||||
|
username: prometheus
|
||||||
|
password_file: /run/secrets/dawarich_metrics_password
|
||||||
|
static_configs:
|
||||||
|
- targets:
|
||||||
|
- dawarich_app:3000
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
replace-with-a-long-random-grafana-readonly-password
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
replace-with-a-long-random-metrics-password
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
replace-with-a-long-random-postgres-password
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
replace-with-a-long-random-url-safe-redis-password
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
replace-with-output-of-openssl-rand-hex-64
|
||||||
@@ -60,6 +60,11 @@ Dieses Dokument listet sensible Daten, deren Ablageorte und die vorgesehene Einb
|
|||||||
| Monitoring Grafana -> InfluxDB | Datasource Token | `/mnt/user/appdata/secrets/monitoring_grafana_influxdb_token.txt` -> Docker Secret `/run/secrets/monitoring_grafana_influxdb_token` | aktiv |
|
| Monitoring Grafana -> InfluxDB | Datasource Token | `/mnt/user/appdata/secrets/monitoring_grafana_influxdb_token.txt` -> Docker Secret `/run/secrets/monitoring_grafana_influxdb_token` | aktiv |
|
||||||
| Grafana OIDC (Authelia) | Client Secret | `/mnt/user/appdata/secrets/grafana_oidc_client_secret` (Klartext, chmod 600) -> Docker Secret `/run/secrets/grafana_oidc_client_secret` -> `GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET__FILE`. Zugehoeriger pbkdf2-Hash liegt im Authelia-Host-Config-Client `grafana` (kein Wert im Repo) | aktiv (2026-06-06) |
|
| Grafana OIDC (Authelia) | Client Secret | `/mnt/user/appdata/secrets/grafana_oidc_client_secret` (Klartext, chmod 600) -> Docker Secret `/run/secrets/grafana_oidc_client_secret` -> `GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET__FILE`. Zugehoeriger pbkdf2-Hash liegt im Authelia-Host-Config-Client `grafana` (kein Wert im Repo) | aktiv (2026-06-06) |
|
||||||
| Mealie OIDC (Authelia) | Client Secret | Stack-ENV `${MEALIE_OIDC_CLIENT_SECRET}` in `/mnt/user/services/stacks/mealie/apps/mealie/.env` (Komodo-Stack-ENV); pbkdf2-Hash im Authelia-Host-Config-Client `mealie` (kein Wert im Repo) | aktiv (2026-06-06) |
|
| Mealie OIDC (Authelia) | Client Secret | Stack-ENV `${MEALIE_OIDC_CLIENT_SECRET}` in `/mnt/user/services/stacks/mealie/apps/mealie/.env` (Komodo-Stack-ENV); pbkdf2-Hash im Authelia-Host-Config-Client `mealie` (kein Wert im Repo) | aktiv (2026-06-06) |
|
||||||
|
| Dawarich | DB Password | `/mnt/user/appdata/secrets/dawarich_postgres_password.txt` -> Docker Secret `/run/secrets/dawarich_postgres_password`; Postgres nutzt `POSTGRES_PASSWORD_FILE`, App/Sidekiq lesen per Entrypoint-Export | geplant |
|
||||||
|
| Dawarich | Redis Password | `/mnt/user/appdata/secrets/dawarich_redis_password.txt` -> Docker Secret `/run/secrets/dawarich_redis_password`; Redis `--requirepass`, App/Sidekiq `REDIS_URL` | geplant |
|
||||||
|
| Dawarich | Rails `SECRET_KEY_BASE` | `/mnt/user/appdata/secrets/dawarich_secret_key_base.txt` -> Docker Secret `/run/secrets/dawarich_secret_key_base` | geplant |
|
||||||
|
| Dawarich Metrics | Basic-Auth Password | `/mnt/user/appdata/secrets/dawarich_metrics_password.txt` -> Docker Secret `/run/secrets/dawarich_metrics_password`; Prometheus `password_file` | geplant |
|
||||||
|
| Grafana -> Dawarich | Read-only DB Password | `/mnt/user/appdata/secrets/dawarich_grafana_ro_password.txt` -> Docker Secret `/run/secrets/dawarich_grafana_ro_password`; Grafana-Env `DAWARICH_GRAFANA_RO_PASSWORD` | geplant |
|
||||||
| Renovate Bot | Gitea Service-Account PAT | `/mnt/user/appdata/secrets/renovate_token.txt` -> Host-Datei (chmod 600), gelesen von `ops/renovate/run-renovate.sh` und an Renovate-Container als `RENOVATE_TOKEN` weitergegeben | aktiv nach Operator-Setup (siehe `docs/RENOVATE.md`) |
|
| Renovate Bot | Gitea Service-Account PAT | `/mnt/user/appdata/secrets/renovate_token.txt` -> Host-Datei (chmod 600), gelesen von `ops/renovate/run-renovate.sh` und an Renovate-Container als `RENOVATE_TOKEN` weitergegeben | aktiv nach Operator-Setup (siehe `docs/RENOVATE.md`) |
|
||||||
| n8n | Encryption Key fuer interne Credential-Verschluesselung | `/mnt/user/appdata/secrets/n8n_encryption_key.txt` (chmod 600) -> Komodo Stack ENV `${N8N_ENCRYPTION_KEY}`; kein `_FILE`-Support im Upstream-Image | aktiv |
|
| n8n | Encryption Key fuer interne Credential-Verschluesselung | `/mnt/user/appdata/secrets/n8n_encryption_key.txt` (chmod 600) -> Komodo Stack ENV `${N8N_ENCRYPTION_KEY}`; kein `_FILE`-Support im Upstream-Image | aktiv |
|
||||||
| n8n | GMX IMAP Login (Mail-Trigger Workflow) | n8n Credentials Store (Typ `imap`), nur in `/mnt/user/appdata/n8n/data` mit `N8N_ENCRYPTION_KEY` verschluesselt | aktiv |
|
| n8n | GMX IMAP Login (Mail-Trigger Workflow) | n8n Credentials Store (Typ `imap`), nur in `/mnt/user/appdata/n8n/data` mit `N8N_ENCRYPTION_KEY` verschluesselt | aktiv |
|
||||||
@@ -108,6 +113,11 @@ Dieses Dokument listet sensible Daten, deren Ablageorte und die vorgesehene Einb
|
|||||||
|-- ha_token_codex
|
|-- ha_token_codex
|
||||||
|-- filebrowser_admin_password.txt
|
|-- filebrowser_admin_password.txt
|
||||||
|-- homelab_smtp_password.txt
|
|-- homelab_smtp_password.txt
|
||||||
|
|-- dawarich_postgres_password.txt
|
||||||
|
|-- dawarich_redis_password.txt
|
||||||
|
|-- dawarich_secret_key_base.txt
|
||||||
|
|-- dawarich_metrics_password.txt
|
||||||
|
|-- dawarich_grafana_ro_password.txt
|
||||||
`-- vaultwarden_admin_token.txt
|
`-- vaultwarden_admin_token.txt
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -43,6 +43,9 @@ Secret-Werte sind nicht enthalten. Es werden nur Secret-Namen, Env-Key-Namen und
|
|||||||
| `immich_machine_learning` | Immich ML | `apps/immich/docker-compose.yml` | intern | `immich_default`, `immich_egress` | `model-cache` | rebuildbar | nein | keine Traefik-Route; `immich_egress` (nicht-internal) nur fuer Modell-Download zu huggingface, sonst scheitert Smart Search/Gesichtserkennung an DNS |
|
| `immich_machine_learning` | Immich ML | `apps/immich/docker-compose.yml` | intern | `immich_default`, `immich_egress` | `model-cache` | rebuildbar | nein | keine Traefik-Route; `immich_egress` (nicht-internal) nur fuer Modell-Download zu huggingface, sonst scheitert Smart Search/Gesichtserkennung an DNS |
|
||||||
| `mealie` | Rezeptverwaltung | `apps/mealie/docker-compose.yml` | `https://mealie.kaleschke.info` | `mealie-postgres`, Traefik | `/mnt/user/appdata/mealie/data` | Tier 2, Borg + `mealie.dump` | ja | App + DB in internem Netz getrennt |
|
| `mealie` | Rezeptverwaltung | `apps/mealie/docker-compose.yml` | `https://mealie.kaleschke.info` | `mealie-postgres`, Traefik | `/mnt/user/appdata/mealie/data` | Tier 2, Borg + `mealie.dump` | ja | App + DB in internem Netz getrennt |
|
||||||
| `mealie-postgres` | Mealie-Datenbank | `apps/mealie/docker-compose.yml` | intern | `mealie_internal` | `/mnt/user/appdata/mealie/postgres18`, archivierter Rollback-Altstand `/mnt/user/appdata/_archive/pg18-immich-rollback-volumes-20260602/mealie-postgres17`, `mealie_postgres_password.txt` | Dump `mealie.dump` | nein | interne DB; PostgreSQL 18 |
|
| `mealie-postgres` | Mealie-Datenbank | `apps/mealie/docker-compose.yml` | intern | `mealie_internal` | `/mnt/user/appdata/mealie/postgres18`, archivierter Rollback-Altstand `/mnt/user/appdata/_archive/pg18-immich-rollback-volumes-20260602/mealie-postgres17`, `mealie_postgres_password.txt` | Dump `mealie.dump` | nein | interne DB; PostgreSQL 18 |
|
||||||
|
| `dawarich_app` | Standort-Historie / Google-Timeline-Ersatz | `apps/dawarich/docker-compose.yml` | `https://dawarich.kaleschke.info` | eigene PostGIS-DB, eigene Redis, Traefik + Authelia, optional Home Assistant Push | `/mnt/user/appdata/dawarich/{postgres17,redis,shared,public,watched,storage}`, `dawarich_*.txt` Secrets | Tier 2, Borg + `dawarich.dump` | ja + Authelia | UI hinter Authelia; API-Key-Tracking-Endpunkte fuer OwnTracks/Overland/Traccar ohne ForwardAuth priorisiert. App und Sidekiq nutzen `freikin/dawarich:1.8.1`; Prometheus-Scrape nach aktueller Dawarich-Doku ueber `dawarich_app:3000/metrics`, Sidekiq-Metriken intern ueber `:9394`. |
|
||||||
|
| `dawarich_db` | Dawarich PostGIS-Datenbank | `apps/dawarich/docker-compose.yml` | intern | `backend_net` | `/mnt/user/appdata/dawarich/postgres17`, `dawarich_postgres_password.txt`, `dawarich_grafana_ro_password.txt` | Dump `dawarich.dump`; raw DB nur bei gleichem PG/PostGIS und sauberem Shutdown | nein | PostGIS 17-3.5 Alpine; Grafana-Read-only-User `dawarich_grafana_ro` per Init-Script |
|
||||||
|
| `dawarich_redis` | Dawarich Cache/Queue-Backend | `apps/dawarich/docker-compose.yml` | intern | `backend_net` | `/mnt/user/appdata/dawarich/redis`, `dawarich_redis_password.txt` | Teil von Dawarich-Restore, aber aus DB/Appdaten rekonstruierbar | nein | Redis 7 Alpine, keine Host-Ports |
|
||||||
| `mail-archiver` | Mail-Archivierung | `apps/mail-archiver/docker-compose.yml` | `https://mail.kaleschke.info` | PostgreSQL 18, Internet/IMAP, Traefik, Authelia | `/mnt/user/appdata/mailarchiver/data-protection-keys` | Tier 2, `postgresql17-mailarchiver.dump` | ja + Authelia | Hybrid-Dienst: `frontend_net` fuer Internet, `backend_net` fuer DB; App-eigene Auth bleibt zusaetzliche Schutzschicht; Dump-Dateiname behaelt den historischen Cluster-Namen |
|
| `mail-archiver` | Mail-Archivierung | `apps/mail-archiver/docker-compose.yml` | `https://mail.kaleschke.info` | PostgreSQL 18, Internet/IMAP, Traefik, Authelia | `/mnt/user/appdata/mailarchiver/data-protection-keys` | Tier 2, `postgresql17-mailarchiver.dump` | ja + Authelia | Hybrid-Dienst: `frontend_net` fuer Internet, `backend_net` fuer DB; App-eigene Auth bleibt zusaetzliche Schutzschicht; Dump-Dateiname behaelt den historischen Cluster-Namen |
|
||||||
| `nextcloud` | Datei-/Cloud-Dienst | `apps/nextcloud/docker-compose.yml` | `https://cloud.kaleschke.info` | eigene PostgreSQL, eigene Redis, Traefik | `/mnt/user/appdata/nextcloud/html`, `/mnt/user/documents/nextcloud-data` | Tier 2, `nextcloud.dump` + Share | ja | native App-Auth ohne zentrale ForwardAuth; WebDAV/CardDAV beachten |
|
| `nextcloud` | Datei-/Cloud-Dienst | `apps/nextcloud/docker-compose.yml` | `https://cloud.kaleschke.info` | eigene PostgreSQL, eigene Redis, Traefik | `/mnt/user/appdata/nextcloud/html`, `/mnt/user/documents/nextcloud-data` | Tier 2, `nextcloud.dump` + Share | ja | native App-Auth ohne zentrale ForwardAuth; WebDAV/CardDAV beachten |
|
||||||
| `nextcloud-postgres` | Nextcloud-Datenbank | `apps/nextcloud/docker-compose.yml` | intern | `nextcloud_internal` | `/mnt/user/appdata/nextcloud/postgres18`, archivierter Rollback-Altstand `/mnt/user/appdata/_archive/pg18-immich-rollback-volumes-20260602/nextcloud-postgres17`, `nextcloud_postgres_password.txt` | `nextcloud.dump`, raw DB nicht primaerer Restore-Weg | nein | interne DB; PostgreSQL 18 |
|
| `nextcloud-postgres` | Nextcloud-Datenbank | `apps/nextcloud/docker-compose.yml` | intern | `nextcloud_internal` | `/mnt/user/appdata/nextcloud/postgres18`, archivierter Rollback-Altstand `/mnt/user/appdata/_archive/pg18-immich-rollback-volumes-20260602/nextcloud-postgres17`, `nextcloud_postgres_password.txt` | `nextcloud.dump`, raw DB nicht primaerer Restore-Weg | nein | interne DB; PostgreSQL 18 |
|
||||||
|
|||||||
@@ -17,8 +17,11 @@ services:
|
|||||||
- prometheus_data:/prometheus
|
- prometheus_data:/prometheus
|
||||||
networks:
|
networks:
|
||||||
- monitoring_net
|
- monitoring_net
|
||||||
|
- backend_net
|
||||||
expose:
|
expose:
|
||||||
- "9090"
|
- "9090"
|
||||||
|
secrets:
|
||||||
|
- dawarich_metrics_password
|
||||||
security_opt:
|
security_opt:
|
||||||
- no-new-privileges:true
|
- no-new-privileges:true
|
||||||
depends_on:
|
depends_on:
|
||||||
@@ -165,6 +168,7 @@ services:
|
|||||||
- -c
|
- -c
|
||||||
- |
|
- |
|
||||||
export GRAFANA_INFLUXDB_TOKEN="$$(cat /run/secrets/monitoring_grafana_influxdb_token)"
|
export GRAFANA_INFLUXDB_TOKEN="$$(cat /run/secrets/monitoring_grafana_influxdb_token)"
|
||||||
|
export DAWARICH_GRAFANA_RO_PASSWORD="$$(cat /run/secrets/dawarich_grafana_ro_password)"
|
||||||
exec /run.sh
|
exec /run.sh
|
||||||
volumes:
|
volumes:
|
||||||
- grafana_data:/var/lib/grafana
|
- grafana_data:/var/lib/grafana
|
||||||
@@ -173,10 +177,12 @@ services:
|
|||||||
networks:
|
networks:
|
||||||
- monitoring_net
|
- monitoring_net
|
||||||
- frontend_net
|
- frontend_net
|
||||||
|
- backend_net
|
||||||
secrets:
|
secrets:
|
||||||
- monitoring_grafana_admin_password
|
- monitoring_grafana_admin_password
|
||||||
- monitoring_grafana_influxdb_token
|
- monitoring_grafana_influxdb_token
|
||||||
- grafana_oidc_client_secret
|
- grafana_oidc_client_secret
|
||||||
|
- dawarich_grafana_ro_password
|
||||||
expose:
|
expose:
|
||||||
- "3000"
|
- "3000"
|
||||||
security_opt:
|
security_opt:
|
||||||
@@ -390,6 +396,8 @@ networks:
|
|||||||
driver: bridge
|
driver: bridge
|
||||||
frontend_net:
|
frontend_net:
|
||||||
external: true
|
external: true
|
||||||
|
backend_net:
|
||||||
|
external: true
|
||||||
dns_net:
|
dns_net:
|
||||||
external: true
|
external: true
|
||||||
|
|
||||||
@@ -409,3 +417,7 @@ secrets:
|
|||||||
file: /mnt/user/appdata/secrets/grafana_oidc_client_secret
|
file: /mnt/user/appdata/secrets/grafana_oidc_client_secret
|
||||||
influxdb3_admin_token:
|
influxdb3_admin_token:
|
||||||
file: /mnt/user/appdata/secrets/influxdb3_admin_token.json
|
file: /mnt/user/appdata/secrets/influxdb3_admin_token.json
|
||||||
|
dawarich_metrics_password:
|
||||||
|
file: /mnt/user/appdata/secrets/dawarich_metrics_password.txt
|
||||||
|
dawarich_grafana_ro_password:
|
||||||
|
file: /mnt/user/appdata/secrets/dawarich_grafana_ro_password.txt
|
||||||
|
|||||||
@@ -0,0 +1,355 @@
|
|||||||
|
{
|
||||||
|
"annotations": {
|
||||||
|
"list": [
|
||||||
|
{
|
||||||
|
"builtIn": 1,
|
||||||
|
"datasource": {
|
||||||
|
"type": "grafana",
|
||||||
|
"uid": "-- Grafana --"
|
||||||
|
},
|
||||||
|
"enable": true,
|
||||||
|
"hide": true,
|
||||||
|
"iconColor": "rgba(0, 211, 255, 1)",
|
||||||
|
"name": "Annotations & Alerts",
|
||||||
|
"type": "dashboard"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"editable": false,
|
||||||
|
"fiscalYearStartMonth": 0,
|
||||||
|
"graphTooltip": 0,
|
||||||
|
"id": null,
|
||||||
|
"links": [],
|
||||||
|
"panels": [
|
||||||
|
{
|
||||||
|
"datasource": {
|
||||||
|
"type": "postgres",
|
||||||
|
"uid": "dawarich-postgres"
|
||||||
|
},
|
||||||
|
"fieldConfig": {
|
||||||
|
"defaults": {
|
||||||
|
"custom": {
|
||||||
|
"hideFrom": {
|
||||||
|
"legend": false,
|
||||||
|
"tooltip": false,
|
||||||
|
"viz": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"mappings": [],
|
||||||
|
"thresholds": {
|
||||||
|
"mode": "absolute",
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"color": "green",
|
||||||
|
"value": null
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"unit": "none"
|
||||||
|
},
|
||||||
|
"overrides": []
|
||||||
|
},
|
||||||
|
"gridPos": {
|
||||||
|
"h": 16,
|
||||||
|
"w": 16,
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
"id": 1,
|
||||||
|
"options": {
|
||||||
|
"basemap": {
|
||||||
|
"config": {},
|
||||||
|
"name": "Layer 0",
|
||||||
|
"type": "default"
|
||||||
|
},
|
||||||
|
"controls": {
|
||||||
|
"mouseWheelZoom": true,
|
||||||
|
"showAttribution": true,
|
||||||
|
"showDebug": false,
|
||||||
|
"showMeasure": false,
|
||||||
|
"showScale": true,
|
||||||
|
"showZoom": true
|
||||||
|
},
|
||||||
|
"layers": [
|
||||||
|
{
|
||||||
|
"config": {
|
||||||
|
"showLegend": true,
|
||||||
|
"style": {
|
||||||
|
"color": {
|
||||||
|
"fixed": "dark-green"
|
||||||
|
},
|
||||||
|
"opacity": 0.55,
|
||||||
|
"rotation": {
|
||||||
|
"fixed": 0,
|
||||||
|
"max": 360,
|
||||||
|
"min": -360,
|
||||||
|
"mode": "mod"
|
||||||
|
},
|
||||||
|
"size": {
|
||||||
|
"fixed": 4,
|
||||||
|
"max": 15,
|
||||||
|
"min": 2
|
||||||
|
},
|
||||||
|
"symbol": {
|
||||||
|
"fixed": "img/icons/marker/circle.svg",
|
||||||
|
"mode": "fixed"
|
||||||
|
},
|
||||||
|
"textConfig": {
|
||||||
|
"fontSize": 12,
|
||||||
|
"offsetX": 0,
|
||||||
|
"offsetY": 0,
|
||||||
|
"textAlign": "center",
|
||||||
|
"textBaseline": "middle"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"location": {
|
||||||
|
"latitude": "latitude",
|
||||||
|
"longitude": "longitude",
|
||||||
|
"mode": "coords"
|
||||||
|
},
|
||||||
|
"name": "Location points",
|
||||||
|
"tooltip": true,
|
||||||
|
"type": "markers"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tooltip": {
|
||||||
|
"mode": "details"
|
||||||
|
},
|
||||||
|
"view": {
|
||||||
|
"allLayers": true,
|
||||||
|
"id": "fit",
|
||||||
|
"lat": 51,
|
||||||
|
"lon": 10,
|
||||||
|
"zoom": 5
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pluginVersion": "13.0.2",
|
||||||
|
"targets": [
|
||||||
|
{
|
||||||
|
"datasource": {
|
||||||
|
"type": "postgres",
|
||||||
|
"uid": "dawarich-postgres"
|
||||||
|
},
|
||||||
|
"editorMode": "code",
|
||||||
|
"format": "table",
|
||||||
|
"rawQuery": true,
|
||||||
|
"rawSql": "SELECT\n to_timestamp(timestamp) AS \"time\",\n ST_Y(lonlat::geometry) AS latitude,\n ST_X(lonlat::geometry) AS longitude,\n accuracy,\n tracker_id\nFROM points\nWHERE $__unixEpochFilter(timestamp)\n AND lonlat IS NOT NULL\nORDER BY timestamp DESC\nLIMIT 20000;",
|
||||||
|
"refId": "A"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"title": "Location Points",
|
||||||
|
"type": "geomap"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"datasource": {
|
||||||
|
"type": "postgres",
|
||||||
|
"uid": "dawarich-postgres"
|
||||||
|
},
|
||||||
|
"fieldConfig": {
|
||||||
|
"defaults": {
|
||||||
|
"color": {
|
||||||
|
"mode": "palette-classic"
|
||||||
|
},
|
||||||
|
"custom": {
|
||||||
|
"axisBorderShow": false,
|
||||||
|
"axisCenteredZero": false,
|
||||||
|
"axisColorMode": "text",
|
||||||
|
"axisLabel": "",
|
||||||
|
"axisPlacement": "auto",
|
||||||
|
"barAlignment": 0,
|
||||||
|
"drawStyle": "bars",
|
||||||
|
"fillOpacity": 70,
|
||||||
|
"gradientMode": "none",
|
||||||
|
"hideFrom": {
|
||||||
|
"legend": false,
|
||||||
|
"tooltip": false,
|
||||||
|
"viz": false
|
||||||
|
},
|
||||||
|
"insertNulls": false,
|
||||||
|
"lineInterpolation": "linear",
|
||||||
|
"lineWidth": 1,
|
||||||
|
"pointSize": 5,
|
||||||
|
"scaleDistribution": {
|
||||||
|
"type": "linear"
|
||||||
|
},
|
||||||
|
"showPoints": "never",
|
||||||
|
"spanNulls": false,
|
||||||
|
"stacking": {
|
||||||
|
"group": "A",
|
||||||
|
"mode": "none"
|
||||||
|
},
|
||||||
|
"thresholdsStyle": {
|
||||||
|
"mode": "off"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"mappings": [],
|
||||||
|
"thresholds": {
|
||||||
|
"mode": "absolute",
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"color": "green",
|
||||||
|
"value": null
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"unit": "km"
|
||||||
|
},
|
||||||
|
"overrides": []
|
||||||
|
},
|
||||||
|
"gridPos": {
|
||||||
|
"h": 8,
|
||||||
|
"w": 8,
|
||||||
|
"x": 16,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
"id": 2,
|
||||||
|
"options": {
|
||||||
|
"legend": {
|
||||||
|
"calcs": [
|
||||||
|
"sum"
|
||||||
|
],
|
||||||
|
"displayMode": "list",
|
||||||
|
"placement": "bottom",
|
||||||
|
"showLegend": true
|
||||||
|
},
|
||||||
|
"tooltip": {
|
||||||
|
"hideZeros": false,
|
||||||
|
"mode": "single",
|
||||||
|
"sort": "none"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pluginVersion": "13.0.2",
|
||||||
|
"targets": [
|
||||||
|
{
|
||||||
|
"datasource": {
|
||||||
|
"type": "postgres",
|
||||||
|
"uid": "dawarich-postgres"
|
||||||
|
},
|
||||||
|
"editorMode": "code",
|
||||||
|
"format": "time_series",
|
||||||
|
"rawQuery": true,
|
||||||
|
"rawSql": "SELECT\n make_date(year, month, 1)::timestamp AS \"time\",\n round((distance::numeric / 1000.0), 2) AS \"km\"\nFROM stats\nWHERE make_date(year, month, 1)::timestamp BETWEEN $__timeFrom() AND $__timeTo()\nORDER BY 1;",
|
||||||
|
"refId": "A"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"title": "Kilometers per Month",
|
||||||
|
"type": "timeseries"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"datasource": {
|
||||||
|
"type": "postgres",
|
||||||
|
"uid": "dawarich-postgres"
|
||||||
|
},
|
||||||
|
"fieldConfig": {
|
||||||
|
"defaults": {
|
||||||
|
"color": {
|
||||||
|
"mode": "palette-classic"
|
||||||
|
},
|
||||||
|
"custom": {
|
||||||
|
"axisBorderShow": false,
|
||||||
|
"axisCenteredZero": false,
|
||||||
|
"axisColorMode": "text",
|
||||||
|
"axisLabel": "",
|
||||||
|
"axisPlacement": "auto",
|
||||||
|
"barAlignment": 0,
|
||||||
|
"drawStyle": "bars",
|
||||||
|
"fillOpacity": 70,
|
||||||
|
"gradientMode": "none",
|
||||||
|
"hideFrom": {
|
||||||
|
"legend": false,
|
||||||
|
"tooltip": false,
|
||||||
|
"viz": false
|
||||||
|
},
|
||||||
|
"insertNulls": false,
|
||||||
|
"lineInterpolation": "linear",
|
||||||
|
"lineWidth": 1,
|
||||||
|
"pointSize": 5,
|
||||||
|
"scaleDistribution": {
|
||||||
|
"type": "linear"
|
||||||
|
},
|
||||||
|
"showPoints": "never",
|
||||||
|
"spanNulls": false,
|
||||||
|
"stacking": {
|
||||||
|
"group": "A",
|
||||||
|
"mode": "none"
|
||||||
|
},
|
||||||
|
"thresholdsStyle": {
|
||||||
|
"mode": "off"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"mappings": [],
|
||||||
|
"thresholds": {
|
||||||
|
"mode": "absolute",
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"color": "green",
|
||||||
|
"value": null
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"unit": "short"
|
||||||
|
},
|
||||||
|
"overrides": []
|
||||||
|
},
|
||||||
|
"gridPos": {
|
||||||
|
"h": 8,
|
||||||
|
"w": 8,
|
||||||
|
"x": 16,
|
||||||
|
"y": 8
|
||||||
|
},
|
||||||
|
"id": 3,
|
||||||
|
"options": {
|
||||||
|
"legend": {
|
||||||
|
"calcs": [
|
||||||
|
"sum"
|
||||||
|
],
|
||||||
|
"displayMode": "list",
|
||||||
|
"placement": "bottom",
|
||||||
|
"showLegend": true
|
||||||
|
},
|
||||||
|
"tooltip": {
|
||||||
|
"hideZeros": false,
|
||||||
|
"mode": "single",
|
||||||
|
"sort": "none"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pluginVersion": "13.0.2",
|
||||||
|
"targets": [
|
||||||
|
{
|
||||||
|
"datasource": {
|
||||||
|
"type": "postgres",
|
||||||
|
"uid": "dawarich-postgres"
|
||||||
|
},
|
||||||
|
"editorMode": "code",
|
||||||
|
"format": "time_series",
|
||||||
|
"rawQuery": true,
|
||||||
|
"rawSql": "SELECT\n date_trunc('day', to_timestamp(timestamp)) AS \"time\",\n count(*) AS \"points\"\nFROM points\nWHERE $__unixEpochFilter(timestamp)\nGROUP BY 1\nORDER BY 1;",
|
||||||
|
"refId": "A"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"title": "Points per Day",
|
||||||
|
"type": "timeseries"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"preload": false,
|
||||||
|
"refresh": "5m",
|
||||||
|
"schemaVersion": 41,
|
||||||
|
"tags": [
|
||||||
|
"dawarich",
|
||||||
|
"location"
|
||||||
|
],
|
||||||
|
"templating": {
|
||||||
|
"list": []
|
||||||
|
},
|
||||||
|
"time": {
|
||||||
|
"from": "now-30d",
|
||||||
|
"to": "now"
|
||||||
|
},
|
||||||
|
"timepicker": {},
|
||||||
|
"timezone": "browser",
|
||||||
|
"title": "Dawarich",
|
||||||
|
"uid": "dawarich",
|
||||||
|
"version": 1,
|
||||||
|
"weekStart": ""
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
apiVersion: 1
|
||||||
|
|
||||||
|
datasources:
|
||||||
|
- name: Dawarich PostgreSQL
|
||||||
|
uid: dawarich-postgres
|
||||||
|
type: postgres
|
||||||
|
access: proxy
|
||||||
|
url: dawarich_db:5432
|
||||||
|
database: dawarich_production
|
||||||
|
user: dawarich_grafana_ro
|
||||||
|
editable: false
|
||||||
|
jsonData:
|
||||||
|
sslmode: disable
|
||||||
|
postgresVersion: 1700
|
||||||
|
timescaledb: false
|
||||||
|
secureJsonData:
|
||||||
|
password: $DAWARICH_GRAFANA_RO_PASSWORD
|
||||||
@@ -36,6 +36,16 @@ scrape_configs:
|
|||||||
- targets:
|
- targets:
|
||||||
- traefik:8082
|
- traefik:8082
|
||||||
|
|
||||||
|
- job_name: dawarich
|
||||||
|
metrics_path: /metrics
|
||||||
|
basic_auth:
|
||||||
|
username: prometheus
|
||||||
|
password_file: /run/secrets/dawarich_metrics_password
|
||||||
|
static_configs:
|
||||||
|
# Dawarich >= 1.7.7 serves aggregated web + Sidekiq metrics here.
|
||||||
|
- targets:
|
||||||
|
- dawarich_app:3000
|
||||||
|
|
||||||
- job_name: blackbox-http
|
- job_name: blackbox-http
|
||||||
metrics_path: /probe
|
metrics_path: /probe
|
||||||
params:
|
params:
|
||||||
|
|||||||
Reference in New Issue
Block a user