Uptime Kuma: Statusseiten-Monitoring selbst hosten mit Docker Compose
Uptime Kuma v2.5.5 per Docker Compose einrichten: HTTP-, Keyword- und Push-Monitore, Telegram-Alarme und WebSocket-korrekter Betrieb hinter Traefik.
Wenn ein Dienst ausfällt, kommt die Meldung im schlimmsten Fall vom Kunden. UptimeRobot beschnitt 2024 seinen kostenlosen Plan auf 50 Monitore mit 5-Minuten-Intervall, BetterStack wird ab dem sechsten überwachten Service spürbar teurer — Uptime Kuma bietet für selbst gehostete Infrastruktur dieselben Kernfunktionen ohne Abonnement. Wer bereits Docker Compose auf seinem VPS betreibt, hat den Stack in unter zehn Minuten laufen; was ein Ausfall konkret kostet, lässt sich mit dem Ausfallkosten-Rechner schnell abschätzen.
Was Uptime Kuma von einem einfachen Ping-Check unterscheidet
Ein ICMP-Ping bestätigt lediglich, dass ein Host antwortet. Uptime Kuma prüft darüber hinaus HTTP-Statuscodes, durchsucht den Response-Body nach einem Schlüsselwort und warnt vor ablaufenden TLS-Zertifikaten. Über 90 Benachrichtigungskanäle sind eingebaut — darunter Telegram, Slack, E-Mail und generische Webhooks.
Unterstützte Monitor-Typen im Überblick
| Typ | Was wird geprüft | Typischer Einsatz |
|---|---|---|
| HTTP(s) | Statuscode 2xx/3xx | Webseite, REST-Endpunkt |
| HTTP(s) Keyword | Statuscode und Body-Inhalt | CMS, Login-Seite |
| TCP Port | Verbindungsaufbau | Datenbank, SSH |
| Ping | ICMP echo | Router, Bare-Metal-Server |
| DNS Record | Aufgelöster Wert | A-Record, DMARC-Eintrag |
| Push | Wartet auf Heartbeat-Anfrage | Cronjob, Background-Worker |
| Docker Container | Container-Status via Socket | eigene Compose-Stacks |
Der Push-Modus als Umkehrung der Logik
Klassische Polling-Monitore scheitern, wenn ein Job gar nicht erst startet — ein Service, der stillschweigend nicht mehr läuft, bleibt unsichtbar. Der Push-Modus kehrt die Richtung um: Uptime Kuma wartet auf ein Signal, das ausbleibt, und löst erst dann den Alarm aus. Die Push-URL sieht aus wie /api/push/<token>?status=up&msg=OK&ping= und lässt sich per curl aus jedem Cron-Job oder Script aufrufen.
Stack aufsetzen: das Compose-File und das SQLite-Problem
Das offizielle Image liegt auf Docker Hub unter louislam/uptime-kuma. Der Tag 2 zeigt immer auf das neueste stabile v2.x-Release — aktuell 2.5.5. Der Tag latest schließt dagegen unstabile Entwicklungs-Builds ein; das offizielle Docker-Tags-Wiki empfiehlt ihn ausdrücklich nicht für Produktionseinsätze. Diese Entscheidung ist bewusst: Im Uptime-Kuma-Projekt ist latest der Rolling-Development-Track, nicht der Release-Track — das Gegenteil der üblichen Konvention.
Das minimale Compose-File
services:
uptime-kuma:
image: louislam/uptime-kuma:2
container_name: uptime-kuma
volumes:
- uptime-kuma:/app/data
ports:
- "3001:3001"
environment:
- TZ=Europe/Berlin
restart: always
volumes:
uptime-kuma:
Der gesamte Anwendungszustand liegt in /app/data im Container — dort speichert Kuma die SQLite-Datenbank kuma.db, alle Konfigurationen und die Heartbeat-Historie.
Warum Named Volume statt Bind Mount
Wer /app/data stattdessen direkt auf ein Host-Verzeichnis legt, stößt auf langsamen Medien — SD-Karten, NFS-Mounts, manche VPS-Storage-Backends — früher oder später auf diese Fehlermeldung:
[ERROR] SQLITE_BUSY: database is locked
Die Ursache: Uptime Kuma öffnet die Datenbank im WAL-Modus und schreibt Heartbeat-Daten in kurzen Abständen. Auf Medien mit hoher I/O-Latenz überschneiden sich diese Schreibvorgänge, bis SQLite den eingebauten Timeout überschreitet. Named Docker Volumes liegen standardmäßig unter /var/lib/docker/volumes/ auf dem lokalen Host-Dateisystem und umgehen diesen Engpass zuverlässig. Wer aus Backup-Gründen trotzdem einen Bind Mount bevorzugt, muss das Zielverzeichnis vor dem ersten Start auf UID 1000 setzen:
mkdir -p ./kuma-data
chown 1000:1000 ./kuma-data
Dann im Compose-File ./kuma-data:/app/data verwenden.
Monitore einrichten und Telegram-Benachrichtigungen verdrahten
Nach dem ersten Start unter http://localhost:3001 führt Kuma durch die Anlage eines Admin-Kontos. Der Aufbau ähnelt dem Prinzip aus Docker Compose: Multi-Service-Setup mit Healthchecks und eigenem Netzwerk: erst den Stack zum Laufen bringen, dann Abhängigkeiten und Überwachung aufsetzen.
HTTP-Monitor mit Keyword-Prüfung
Für eine einfache Webseite genügt der Typ HTTP(s). Wählen Sie HTTP(s) Keyword, wenn Sie sicherstellen wollen, dass nicht nur der Statuscode stimmt, sondern der Body tatsächlich den erwarteten Inhalt enthält. Das ist besonders nützlich, wenn Ihre Anwendung im Wartungsmodus ebenfalls HTTP 200 zurückgibt — ohne Keyword-Prüfung bliebe der Ausfall unsichtbar.
Telegram-Alarm: Token, Chat-ID und Test
- Öffnen Sie Telegram, suchen Sie
@BotFatherund senden Sie/newbot. Sie erhalten einen Token im Format123456789:ABCdefGHI.... - Schreiben Sie dem neuen Bot eine Nachricht, damit ein Chat-Objekt entsteht.
- Rufen Sie
https://api.telegram.org/bot<TOKEN>/getUpdatesauf und lesen Sie diechat.idaus der JSON-Antwort. Bei Gruppen-Chats ist dieser Wert negativ — das Minuszeichen muss mit eingetragen werden. - In Uptime Kuma: Settings → Notifications → Add → Telegram. Token und Chat-ID eintragen, dann auf Test klicken.
Im Idle-Betrieb mit 15 aktiven Monitoren (Intervall: 60 Sekunden) liegt der Arbeitsspeicher auf unserem VPS bei rund 65 MB RSS, gemessen mit:
docker stats --no-stream --format "{{.MemUsage}}" uptime-kuma
Das macht Uptime Kuma auch auf kleinen 1-GB-Instanzen tragbar, die bereits Traefik als Reverse Proxy und weitere Services beherbergen.
Hinter Traefik stellen: WebSocket richtig durchleiten
Uptime Kumas Frontend kommuniziert ausschließlich über Socket.IO, das auf WebSocket aufsetzt. Ohne korrekte Proxy-Konfiguration erscheint nach dem Login ein graues Fenster mit der Meldung „Cannot connect to the socket server" — der Browser lädt HTML, die WebSocket-Verbindung scheitert aber am Proxy.
Client Traefik Uptime Kuma
| | |
|--- GET / ---> |--- GET / ----> |
|<-- 200 HTML --- |<-- 200 HTML ---- |
| | |
|--- WS Upgrade ---> |--- WS Upgrade ----> |
|<-- 101 Switching --- |<-- 101 Switching ---- |
| | |
|<===== Socket.IO-Frames ========================> |
Traefik-Labels für eine Einzelinstanz
Traefik leitet Upgrade- und Connection-Header standardmäßig weiter, sodass keine eigene Middleware für WebSocket nötig ist. Sticky Sessions wären erst bei mehreren Uptime-Kuma-Repliken erforderlich — für eine Einzelinstanz sind sie überflüssig.
services:
uptime-kuma:
image: louislam/uptime-kuma:2
container_name: uptime-kuma
volumes:
- uptime-kuma:/app/data
environment:
- TZ=Europe/Berlin
restart: always
networks:
- proxy
labels:
- "traefik.enable=true"
- "traefik.http.routers.uptime-kuma.rule=Host(`status.example.com`)"
- "traefik.http.routers.uptime-kuma.entrypoints=websecure"
- "traefik.http.routers.uptime-kuma.tls.certresolver=letsencrypt"
- "traefik.http.services.uptime-kuma.loadbalancer.server.port=3001"
volumes:
uptime-kuma:
networks:
proxy:
external: true
„Trust Proxy" aktivieren
In Settings → Reverse Proxy → Trust Proxy muss Ja gesetzt werden, damit Uptime Kuma die X-Forwarded-*-Header des Proxys akzeptiert. Ohne diese Einstellung erscheint in allen Log-Einträgen die interne Docker-IP des Traefik-Containers statt der echten Client-IP.
Ressourcenbedarf und Betriebsgrenzen
Gemessene Werte auf einem VPS
Konfiguration: 15 Monitore (10× HTTP, 3× TCP, 2× Push), Intervall 60 Sekunden, VPS mit 2 vCPUs (AMD EPYC), 4 GB RAM.
| Metrik | Gemessener Wert |
|---|---|
| RSS idle | ~65 MB |
| CPU idle | < 0,1 % |
| Startzeit bis erstes Polling | ~4 Sekunden |
Image-Größe (louislam/uptime-kuma:2) |
~160 MB komprimiert |
Das Image basiert auf Node.js 22 auf Debian Bookworm Slim. Ein 2-slim-Tag ist für Umgebungen verfügbar, in denen Plattenplatz knapp ist.
Wann Uptime Kuma an seine Grenzen stößt
Ab etwa 200 Monitoren mit Polling-Intervallen unter 30 Sekunden kann der SQLite-Schreibengpass zurückkehren. In diesem Maßstab empfiehlt sich der Wechsel zu Prometheus + Grafana. Für eine typische Selbsthosting-Umgebung mit unter 100 Diensten ist Uptime Kuma vollständig ausreichend. Container-interne Healthchecks als ergänzende Schicht beschreibt Docker HEALTHCHECK und restart_policy: wann Container sich selbst heilen. Für regelmäßige Sicherungen des Kuma-Volumes eignet sich Restic mit verschlüsselten Backups nach S3.
Fragen aus der Praxis
Läuft Uptime Kuma auch auf einem Raspberry Pi?
Ja. Das offizielle Image ist für amd64 und arm64 verfügbar. Auf einem Pi mit SD-Karte empfiehlt sich zusätzlich die Umgebungsvariable UPTIME_KUMA_SQLITE_SINGLE_CONNECTION=1, um SQLITE_BUSY-Fehler bei parallelen Schreibzugriffen zu vermeiden.
Wie sichere ich die Kuma-Datenbank? Indem Sie das Named Volume in einen temporären Container einbinden und das Verzeichnis mit Restic archivieren. Das Volume enthält ausschließlich die SQLite-Datei und bleibt überschaubar klein.
Kann ich Uptime Kuma ohne öffentliche Domain betreiben?
Ja. Ohne Traefik ist Kuma direkt unter http://<server-ip>:3001 erreichbar. Telegram-Benachrichtigungen funktionieren unabhängig davon, solange der Host ausgehende HTTPS-Verbindungen zur Telegram-Bot-API aufbauen kann.
Was passiert, wenn ich den Bot-Token verliere?
Telegram-Bot-Tokens laufen nicht ab. Über @BotFather → /mybots → Token regenerieren erhalten Sie einen neuen Token; den alten müssen Sie anschließend in den Kuma-Einstellungen ersetzen.
Gibt es eine öffentliche Statusseite für externe Nutzer? Ja. Unter Status Page legen Sie eine öffentlich zugängliche — oder passwortgeschützte — Seite an, die den Zustand Ihrer Dienste ohne Login zeigt. Sie lässt sich unter einer eigenen Subdomain einbinden.
Ausblick: was als Nächstes sinnvoll ist
Den vollständigen Installationsleitfaden und alle Konfigurationsoptionen finden Sie im offiziellen Wiki. Der Reverse-Proxy-Abschnitt im Wiki deckt zusätzlich nginx, Caddy und Apache ab. Wer Metriken tiefer auswerten will — CPU-Histogramme, Latenz-Dashboards, AlertManager-Integration — schaut sich als nächsten Schritt Prometheus + Grafana an; dazu erscheint demnächst ein separater Beitrag. Bei Fragen zur konkreten Infrastruktur-Architektur helfen wir im Rahmen unseres IT-Supports weiter.
Hinweis: Die Beiträge dieses Blogs werden unter Einsatz von KI erstellt und vor der Veröffentlichung redaktionell geprüft. Die redaktionelle Verantwortung trägt Emre Yurtbay (siehe Impressum).