Synthetisches Verfügbarkeits-Monitoring: Uptime Kuma Probes, Docker-Socket-Proxy, Push-Heartbeats & Prometheus-Metriken
Erstellt: 06.11.2026 Aktualisiert: 06.11.2026
Management Summary: Zu spät zu bemerken, dass ein Dienst, ein TLS-Zertifikat oder ein Backup-Cronjob unbemerkt vor Wochen ausgefallen ist, untergräbt das Vertrauen in jede Infrastruktur. Dieser Leitfaden beschreibt das Produktiv-Deployment von Uptime Kuma als synthetisches Black-Box-Überwachungssystem. Schwerpunkte sind aktive Multi-Protokoll-Prüfungen (HTTP(s) JSONPath, TCP, DNSSEC, gRPC, PostgreSQL), Dead-Man's-Switch Push-Heartbeats für asynchrone Backup-Jobs, schreibgeschütztes Container-Monitoring und nativer
/metrics-Export für Prometheus und Grafana.
-
Multi-Protokoll Black-Box Probes
Prüft HTTP/2/3 Statuscodes, JSONPath-Inhalte, TCP-Ports, DNS-Zonenauflösung und Datenbankverbindungen im Sekundentakt.
-
Dead-Man's-Switch Push-URLs
Überwacht periodische Cronjobs, Systemd-Timer und isolierte Nodes ohne eingehenden Netzwerkzugriff über regelmäßige ausgehende Webhook-Pings.
-
Proaktive X.509-Ablaufwarnungen
Liest TLS-Zertifikatsketten bei jeder Prüfung aus und alarmiert 21, 14 und 7 Tage vor Ablauf über strukturierte Benachrichtigungskanäle.
-
Nativer Prometheus-Exporter
Stellt
monitor_status,monitor_response_timeund Zertifikatsrestlaufzeiten unter/metricsfür langfristige Grafana-SLAs bereit.
1. Architektur: Aktive Probes vs. Passive Push-Heartbeats
Uptime Kuma kombiniert zwei grundlegende Überwachungsmethoden in einer Node.js/Vue.js-Anwendung mit SQLite-WAL-Datenbank:
- Aktive Pull-Prüfungen: Uptime Kuma initiiert periodisch ausgehende Verbindungen (z. B. alle 60 Sekunden), um Erreichbarkeit, TLS-Gültigkeit und Anwendungs-Health-Endpunkte zu validieren.
- Passive Push-Heartbeats (Dead-Man's Switch): Zeitgesteuerte Hintergrundaufgaben (wie nächtliche
borgmatic- oderrestic-Backups) rufen nach erfolgreicher Ausführung eine eindeutige Webhook-URL auf (?status=up&msg=OK&ping=1420). Bleibt der Aufruf im definierten Zeitfenster aus, löst Uptime Kuma Alarm aus.
%%{init: {'flowchart': {'wrappingWidth': 600, 'subGraphTitleMargin': {'top': 15, 'bottom': 15}}}}%%
flowchart TB
subgraph Targets["Überwachte Infrastruktur"]
WebApps["HTTPS / JSON APIs<br/>TLS-Ablauf + Keywords"]
DNSNode["Unbound / Pi-hole<br/>DNS A / DNSSEC Probe"]
CronJob["Nächtlicher BorgBackup-Timer<br/>Ausgehender curl Push"]
end
subgraph KumaEngine["Uptime Kuma Core (SQLite WAL)"]
ProbeLoop["Async Probe Scheduler<br/>Retry- & Flapping-Filter"]
PushEndpoint["Push Webhook Receiver<br/>/api/push/<token>"]
PromExporter["Prometheus /metrics<br/>SLA- & Latenz-Gauges"]
end
subgraph AlertChannels["Benachrichtigungskanäle"]
Notify["ntfy / Matrix / Telegram<br/>Gotify / SMTP"]
Grafana["Prometheus + Grafana<br/>Langfristige SLA-Trends"]
end
ProbeLoop -->|"60s Polling"| WebApps
ProbeLoop -->|"UDP/TCP 53 Query"| DNSNode
CronJob -->|"HTTPS GET Heartbeat"| PushEndpoint
ProbeLoop --> Notify
PushEndpoint --> Notify
PromExporter -->|"Scrape :3001/metrics"| Grafana
2. Abgesichertes Container-Deployment mit Socket Proxy
Um lokale Docker-Container zu überwachen, ohne /var/run/docker.sock ungeschützt einzubinden, wird ein schreibgeschützter socket-proxy im internen Netzwerk kuma_socket_net vorgeschaltet:
services:
kuma-socket-proxy:
image: lscr.io/linuxserver/socket-proxy:latest
container_name: kuma-socket-proxy
restart: unless-stopped
read_only: true
tmpfs:
- /run
environment:
CONTAINERS: 1
POST: 0
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
networks:
- kuma_socket_net
uptime-kuma:
image: louislam/uptime-kuma:1
container_name: uptime-kuma
restart: unless-stopped
depends_on:
- kuma-socket-proxy
ports:
- "127.0.0.1:3001:3001/tcp"
environment:
TZ: "Europe/Berlin"
UPTIME_KUMA_DISABLE_FRAME_SAMEORIGIN: "false"
NODE_EXTRA_CA_CERTS: "/etc/ssl/certs/caddy-internal-root-ca.pem"
volumes:
- ./data:/app/data:Z
- /usr/local/share/ca-certificates/caddy-internal-root-ca.crt:/etc/ssl/certs/caddy-internal-root-ca.pem:ro
networks:
- kuma_socket_net
- proxy_net
networks:
kuma_socket_net:
internal: true
proxy_net:
external: true
In der Uptime Kuma Weboberfläche unter Einstellungen → Docker-Hosts wählen Sie TCP / HTTP mit der Daemon-URL http://kuma-socket-proxy:2375.
3. Alarmmüdigkeit vermeiden: Retry- & Flapping-Strategie
Kurze Netzwerkspitzen oder Container-Neustarts sollten keine Fehlalarme auslösen. Konfigurieren Sie die zweistufige Zustandsprüfung:
| Parameter | Empfohlener Wert | Verhalten der Status-Engine |
|---|---|---|
| Heartbeat Intervall | 60s |
Standardabfrageintervall im Zustand UP. |
| Wiederholungen (Retries) | 3 |
Anzahl aufeinanderfolgender Fehlversuche, bevor der Zustand auf DOWN wechselt. |
| Wiederholungsintervall | 20s |
Beschleunigtes Prüfintervall nach erstem Fehlschlag (PENDING). Zeit bis Alarmierung: $60\text{s} + (3 \times 20\text{s}) = 120\text{s}$. |
| Erneutes Senden | 0 (oder alle 30 Durchläufe) |
Verhindert Überflutung des Postfachs bei länger anhaltenden Ausfällen. |
WebSocket-Anforderung am Reverse Proxy (Upgrade: websocket)
Uptime Kumas Oberfläche kommuniziert über Socket.IO WebSockets. Achten Sie darauf, dass der vorgelagerte Proxy WebSocket-Header korrekt weiterleitet (proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade";), andernfalls verbleibt das Dashboard im Verbindungsaufbau.
4. Push-Heartbeats in Backup-Skripte einbinden
Erstellen Sie einen Push-Monitor mit einem 24-Stunden-Intervall (86400s). Das folgende Wrapper-Skript misst die Laufzeit (ping in ms) und übermittelt den Status an Uptime Kuma:
#!/usr/bin/env bash
set -euo pipefail
KUMA_PUSH_URL="https://status.nejat-hakan.de/api/push/x9Km2pL8qR"
START_MS=$(date +%s%3N)
if "$@"; then
END_MS=$(date +%s%3N)
DURATION_MS=$((END_MS - START_MS))
curl -fsS --retry 3 "${KUMA_PUSH_URL}?status=up&msg=OK&ping=${DURATION_MS}" >/dev/null
else
EXIT_CODE=$?
curl -fsS --retry 3 "${KUMA_PUSH_URL}?status=down&msg=Failed_Exit_${EXIT_CODE}" >/dev/null
exit "${EXIT_CODE}"
fi
5. Metriken in Prometheus einbinden
Uptime Kuma stellt Metriken unter /metrics bereit. Nutzen Sie Ihren API-Schlüssel als Passwort:
scrape_configs:
- job_name: "uptime_kuma"
scrape_interval: 30s
metrics_path: "/metrics"
scheme: "http"
basic_auth:
username: "prometheus"
password_file: "/etc/prometheus/secrets/kuma_api_key"
static_configs:
- targets: ["127.0.0.1:3001"]
Metrikausgabe via curl prüfen: