📅 Juni 2026 · Letztes Update: 07.06.2026
TL;DR
Ein Uptime Kuma auf einem externen Server überwacht alle Dienste. Fällt einer aus, schickt Kuma eine Telegram-Nachricht an einen Bot. Ein DevOps-Agent liest die Nachricht, prüft den RepairbyBot-Tag und startet — wenn er darf — automatisch den betroffenen Docker-Container neu. Keine LLM-Tokens, keine manuellen Eingriffe: Ein 150-Zeilen-Bash-Script macht alles autonom.
Stack: Uptime Kuma · Telegram Bot API · Bash · Docker · SQLite · SSH
📖 Inhalt
1. Warum Monitoring mit Selbstheilung?
Klassisches Monitoring macht nur die Hälfte des Jobs: Es sagt dir, dass etwas kaputt ist. Die Frage „und wer fixt das jetzt?" bleibt offen — und landet um 3 Uhr nachts auf deinem Handy.
Die Lösung: Monitoring + Auto-Repair als geschlossener Kreislauf. Uptime Kuma erkennt Downtime → Telegram benachrichtigt den DevOps-Agenten → Der Agent prüft, ob er reparieren darf → Wenn ja: Container-Neustart, Verifikation, Erfolgsmeldung. Wenn nein: Eskalation mit Kontext.
Das Kernprinzip:
- Getrennte Instanz: Kuma läuft auf einem anderen Server als die überwachten Dienste. Fällt der Produktivserver komplett aus, läuft Kuma weiter und meldet den Ausfall.
- Explizite Freigabe: Nicht jeder Dienst darf automatisch repariert werden — der
RepairbyBot-Tag entscheidet. Kein Tag = kein Auto-Repair. - 3-Strike-Regel: Kein盲er Alarm. Erst nach 3 aufeinanderfolgenden Downtime-Checks (9 Minuten) wird der Alarm ausgelöst und die Reparatur gestartet.
- LLM-frei: Ein einfaches Bash-Script, getriggert per Cron. Kostet keine API-Tokens, läuft zuverlässig und deterministisch.
2. Architektur: Getrennte Instanzen
Der Monitoring-Server ist physisch vom Produktivserver getrennt — ein essenzielles Design-Prinzip:
┌─────────────────────────┐ ┌──────────────────────────┐
│ Monitoring-Server │ │ Produktiv-Server │
│ (Hetzner Cloud) │ │ (Lokales RZ) │
│ │ │ │
│ Uptime Kuma :3001 │────▶│ hotzmatic.com │
│ ┌─ SQLite DB │ │ Docker: nginx + sites │
│ │─ Monitore (30+) │ │ Gateway + API │
│ │─ Tags (RepairbyBot) │ │ Datenbanken │
│ │─ Heartbeat-Historie │ │ │
│ └──────────────────────│ │ │
│ │ │ │
│ 🔴 DOWN → Telegram ────│────▶│ Telegram-Gruppe │
│ │ │ "IT Infrastructure" │
└─────────────────────────┘ └──────────────────────────┘
│
▼
┌──────────────┐
│ DevOps-Agent │
│ (Bash-Script) │
│ │
│ Prüft Tag │
│ SSH → Docker │
│ restart │
│ Verifikation │
└──────────────┘
💡 Warum getrennte Instanzen? Würde Kuma auf demselben Server laufen, den es überwacht, wäre es beim Server-Ausfall selbst betroffen — und könnte keinen Alarm mehr senden. Die externe Instanz garantiert, dass Downtime immer erkannt und gemeldet wird.
3. Uptime Kuma Setup
3.1 Docker Compose
Uptime Kuma läuft als einzelner Docker-Container mit Host-Networking — schlank, kein Reverse Proxy nötig (die Monitoring-Instanz ist nur intern erreichbar):
# docker-compose.yml
services:
uptime-kuma:
image: louislam/uptime-kuma:2
network_mode: host
restart: unless-stopped
volumes:
- ./kuma:/app/data
network_mode: host gibt Kuma direkten Zugriff auf das Host-Netzwerk — es kann alle Dienste auf allen Interfaces erreichen. Das Volume ./kuma:/app/data persistiert die SQLite-Datenbank mit allen Monitoren, Heartbeats und Tags.
3.2 Monitore anlegen
Monitore folgen einer strengen Namenskonvention: {STANDORT} - {Dienst} — das gruppiert sie automatisch in der Sidebar:
| Präfix | Standort | Beispiele |
|---|---|---|
| DCF | Hetzner Cloud Finnland | DCF - Docker, DCF - DNS, DCF - Dashboard |
| GD1 | Lokales RZ | GD1 - hotzmatic.com, GD1 - Factory Core |
| DCE | Externe SaaS | DCE - Mail Infrastructure |
3.3 SQLite — das Geheimnis der Automatisierung
Uptime Kuma hat keine REST-API für Management-Operationen. Alle Automatisierung läuft über direkten SQLite-Zugriff:
# Alle Monitore mit Tags abfragen
ssh monitoring-host "docker exec uptime-kuma sqlite3 /app/data/kuma.db -json '
SELECT m.name, t.name as tag, mt.value
FROM monitor m
JOIN monitor_tag mt ON m.id = mt.monitor_id
JOIN tag t ON mt.tag_id = t.id
WHERE m.active = 1
ORDER BY m.name;
'"
💡 SQLite statt REST: Uptime Kuma nutzt intern WebSockets (Socket.IO), hat aber keine dokumentierte REST-API für CRUD-Operationen. SQLite-Direktzugriff ist die zuverlässigste Methode für Automation — schneller als Browser-Automation und komplett deterministisch.
4. Telegram-Integration
Downtime-Alarme landen in einer dedizierten Telegram-Gruppe. Der Ablauf:
- Bot erstellen via @BotFather → API-Token
- Bot in Gruppe einladen und zum Admin machen
- Chat-ID ermitteln via
getUpdates-API - In Kuma einrichten: Settings → Notifications → Telegram → Token + Chat-ID
Kuma sendet bei Statuswechsel automatisch:
🔴 DCF - Dashboard is down
Monitor: DCF - Dashboard
Status: Down
Time: 07.06.2026, 14:23:15
URL: https://dashboard.example.com
Error: timeout
⚠️ Bot braucht Admin-Rechte: Ohne Admin-Rechte in der Gruppe kann der Bot keine Nachrichten senden. Nach dem Einladen in der Gruppe auf „Administrator ernennen" klicken.
5. Tag-System: RepairbyBot
Nicht jeder Dienst darf automatisch repariert werden. Die Entscheidung trifft ein simples Tag-System in Kuma:
| Tag | Wert | Bedeutung |
|---|---|---|
RepairbyBot | True | ✅ Bot darf reparieren (Docker restart) |
RepairbyBot | False | ❌ Nur Alarm, keine automatische Reparatur |
Host | IP-Adresse | Welcher Server hostet den Dienst |
Tags werden direkt in der SQLite-Datenbank gesetzt — viel schneller als die UI für dutzende Monitore:
# RepairbyBot=True für alle DCF-Monitore
ssh monitoring-host "docker exec uptime-kuma sqlite3 /app/data/kuma.db '
INSERT INTO monitor_tag (monitor_id, tag_id, value)
SELECT m.id, 1, \"True\"
FROM monitor m
WHERE m.name LIKE \"DCF - %\" AND m.active = 1;
'"
Erreichbarkeit bestimmt den Tag-Wert: Nur Dienste, die per SSH vom Agenten erreichbar sind, bekommen RepairbyBot=True. Dienste im lokalen Netz (andere Subnetze) sind per Definition False — der Bot kann sie nicht erreichen, also auch nicht reparieren.
💡 Tag-Änderungen nur per SQL: Die Kuma-UI erlaubt keine nachträgliche Änderung von Tag-Werten — nur Löschen und Neu-Anlegen. Massen-Updates immer per UPDATE monitor_tag SET value = ... direkt in SQLite.
6. Auto-Repair-Script
Das Herzstück: Ein 150-Zeilen-Bash-Script, das per Cron alle 3 Minuten läuft — komplett LLM-frei, null Token-Verbrauch.
6.1 Der Ablauf
1. SQL-Abfrage: Alle RepairbyBot=True Monitore mit status=0 (DOWN)
2. Für jeden: Strike-Counter hochzählen (State-Datei)
3. Bei 3 Strikes (9 Minuten): Alarm per Telegram
4. SSH zum Produktivserver → docker restart aller exited Container
5. 60s warten → Heartbeat-Status erneut prüfen
6. Erfolg: "✅ Repariert" in Telegram
Fehlschlag: "❌ Reparatur fehlgeschlagen" + Logs
6.2 Kernlogik (Auszug)
#!/bin/bash
MAX_STRIKES=3
# 1. Aktuelle Downtimes abfragen (nur RepairbyBot=True)
DOWN_JSON=$(ssh monitoring-host \
"docker exec uptime-kuma sqlite3 /app/data/kuma.db -json '
SELECT m.id, m.name, h.msg
FROM monitor m
JOIN monitor_tag mt ON m.id = mt.monitor_id
AND mt.tag_id = 1 AND mt.value = \"True\"
LEFT JOIN heartbeat h ON h.id = (
SELECT id FROM heartbeat
WHERE monitor_id = m.id ORDER BY time DESC LIMIT 1
)
WHERE h.status = 0 AND m.active = 1;
'")
# 2. Strikes zählen
for monitor in $DOWN_MONITORS; do
COUNT=$((COUNT + 1))
if [ $COUNT -ge $MAX_STRIKES ]; then
tg_send "⚠️ Downtime gesichert: $NAME — starte Reparatur..."
# 3. Reparieren: Docker-Container neustarten
ssh prod-host "docker restart $(docker ps -aq --filter status=exited)"
sleep 60
# 4. Verifikation
if kuma_status_check $MONITOR_ID; then
tg_send "✅ Repariert: $NAME ist wieder online!"
else
tg_send "❌ Reparatur fehlgeschlagen: $NAME"
fi
fi
done
6.3 Cron-Job
Das Script läuft alle 3 Minuten als no_agent-Job — kein LLM, keine API-Kosten:
# Cron: alle 3 Minuten, nur Script, kein Agent
Schedule: every 3m
Script: repair-agent.sh
No-Agent: true → stdout wird direkt delivered
⚠️ 3-Strike-Fenster: Bei 60-Sekunden-Check-Intervall von Kuma + 3-Minuten-Cron des Scripts ergeben sich etwa 9 Minuten vom ersten Ausfall bis zur Reparatur. Das ist bewusst konservativ — verhindert盲e Aktionen bei kurzen Netzwerkaussetzern.
7. Betrieb & Lessons Learned
Was gut läuft
- Getrennte Instanz nie betroffen: Egal was auf dem Produktivserver passiert — Kuma läuft und meldet. Kein „der Server ist down, aber keiner weiß es"-Szenario.
- SQLite ist schneller als jede API: Tag-Queries in <100ms, keine Authentifizierung, keine Sessions. Für Automation unschlagbar.
- Bash statt LLM spart massiv Tokens: 3-Minuten-Takt × 480 Läufe/Tag = 480 Mal kein LLM-Aufruf. Bei einem Modell mit $0.14/M-Token summiert sich das schnell.
- RepairbyBot-Tag als Sicherheitsbarriere: Kein Risiko, dass der Bot versehentlich kritische Produktivdienste neustartet. Nur explizit freigegebene Dienste sind betroffen.
Lessons Learned
- Neue Monitore ohne Heartbeat lösen False-Alarms aus: Ein frisch angelegter Monitor hat noch keinen Heartbeat-Eintrag — ein
IS NULLin der Abfrage wertet ihn fälschlich als DOWN. Fix:WHERE h.status = 0(nur existierende Heartbeats, keinIS NULL). - SQLite WAL-Mode erlaubt paralleles Lesen: Uptime Kuma nutzt WAL (Write-Ahead Logging) — das Script kann die DB lesen, während Kuma schreibt. Keine Locks, keine Race Conditions.
- Strike-State-Datei ist kritisch: Ohne State würde jeder Poll einen neuen Alarm auslösen.
/tmp/kuma-monitor-state.txtzählt Strikes pro Monitor — und wird zurückgesetzt, sobald der Monitor wieder UP ist. - Erholungserkennung nicht vergessen: Das Script prüft nicht nur auf DOWN, sondern auch: „War vorher DOWN, ist jetzt UP?" → State-Eintrag löschen und „Alle Dienste online"-Nachricht senden.
Monitoring des Monitorings
- Kuma-Health:
curl https://uptime.hotzmatic.com→ 200 = Kuma selbst ist erreichbar - Cron-Status:
hermes cronjob list→ checken ob der Repair-Job läuft - Script-Logs:
hermes cronjob log <job-id>→ letzte Ausgaben des Repair-Scripts
8. Fazit & Ausblick
✅ Das funktioniert
- Getrennte Monitoring-Instanz (Hetzner)
- Telegram-Alarme mit Bot-Integration
- 3-Strike-Regel gegen盲e Alarme
- Auto-Restart per Docker + SSH
- RepairbyBot-Tag als Sicherheits-Gate
- LLM-frei: 0 Token-Kosten
🔜 Geplant
- KI-Agent für komplexe Diagnosen
- Service-Restart statt Docker-Restart
- Metriken-basierte Schwellwerte
- Öffentliche Status-Page
Die Kombination Uptime Kuma + Telegram + Bash-Script ist ein Paradebeispiel für pragmatische Automatisierung: einfache Bausteine, klare Verantwortlichkeiten, null laufende Kosten. Die getrennte Instanz und das Tag-System sorgen für Sicherheit — der Bot repariert nur, was er reparieren darf, und nur, was er erreichen kann.
🤖 KI-Agenten-Integration
Für komplexere Fehler (die über „Container neustarten" hinausgehen) ist ein KI-DevOps-Agent in Vorbereitung. Er analysiert Logs, prüft Abhängigkeiten und entscheidet kontextbasiert — aber nur, wenn der RepairbyBot-Tag es erlaubt. Der einfache Bash-Repair bleibt als erste Verteidigungslinie bestehen.
Disclaimer: Persönliches Projekt. Uptime Kuma ist Open Source (MIT). Keine Affiliate-Links. Die beschriebene Architektur reflektiert den tatsächlichen Produktivbetrieb.