Zum Inhalt springen
← Alle Beiträge
· 7 Min. Lesezeit· Von

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.

Uptime KumaDockerMonitoringSelf-HostingTraefikTelegramDevOps

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

  1. Öffnen Sie Telegram, suchen Sie @BotFather und senden Sie /newbot. Sie erhalten einen Token im Format 123456789:ABCdefGHI....
  2. Schreiben Sie dem neuen Bot eine Nachricht, damit ein Chat-Objekt entsteht.
  3. Rufen Sie https://api.telegram.org/bot<TOKEN>/getUpdates auf und lesen Sie die chat.id aus der JSON-Antwort. Bei Gruppen-Chats ist dieser Wert negativ — das Minuszeichen muss mit eingetragen werden.
  4. 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).

Projekt besprechen