Zum Hauptinhalt springen
S-EDV news
← Alle Anleitungen
📘 Anleitung Monitoring 05.07.2026 · 10 min Lesezeit

Gatus mit Docker installieren: Entwicklerorientiertes Status-Dashboard für HTTP, DNS und ICMP

Gatus ist ein schlankes, konfigurations-getriebenes Status-Dashboard, das Dienste per HTTP, DNS, TCP und ICMP überwacht und bei Schwellenwert-Verletzungen Alarme via Slack, PagerDuty oder E-Mail auslöst – alles in einem einzigen Docker-Container mit nur ~40 MB RAM.

Gatus mit Docker installieren: Entwicklerorientiertes Status Dashboard für HTTP, DNS und ICMP mit Docker Container, Uptime Monitoring, API Überwachung, Statusseiten, Benachrichtigungen und Self Hosting für Server, Webseiten und Netzwerkdienste.

Wer Dienste professionell betreibt, braucht mehr als ein einfaches „ist der Server up?"-Skript. Gatus ist ein entwicklerorientiertes, selbst gehostetes Health-Dashboard, das Endpunkte per HTTP/HTTPS, ICMP, TCP, DNS, WebSocket, gRPC und weiteren Protokollen überwacht. Es bewertet Antworten anhand konfigurierbarer Bedingungen – etwa Status-Code, Antwortzeit oder Zertifikatsablauf – und löst bei definierten Schwellenwerten Alarme über mehr als 30 Provider aus: Slack, PagerDuty, E-Mail, Discord, Teams oder Telegram. Das Besondere: Gatus kombiniert eine öffentliche Statusseite und internes Monitoring in einem einzigen Container. Mit rund 40 MB RAM für 50 Endpunkte und über 11.000 GitHub-Stars ist es die eleganteste Lösung für transparentes Service-Monitoring im KMU-Umfeld und bei ambitionierten Selfhostern.

Voraussetzungen

  1. Docker Engine 20.10+ und Docker Compose v2 (Befehl: docker compose, nicht docker-compose) auf einem Linux-Host, einer VM oder einem NAS mit Docker-Unterstützung. Noch nicht installiert? Siehe Docker und Docker Compose auf Linux installieren.
  2. Mindestens 50 MB RAM und 100 MB freier Speicher (ohne Datenbank); für die PostgreSQL-Variante zusätzlich ~256 MB RAM.
  3. Einen Texteditor (nano, VS Code o. ä.) für config.yaml und .env.
  4. curl oder wget zum Testen der Endpunkte sowie einen Browser für das Dashboard.
  5. Optional: Slack-Webhook-URL, PagerDuty Integration-Key oder SMTP-Zugangsdaten für Alerting-Tests.
  6. Optional: einen Reverse Proxy (z. B. Nginx Proxy Manager oder Traefik) für HTTPS-Zugriff von außen. Grundlagen dazu in Traefik als Docker-Reverse-Proxy einrichten.

Schritt 1: Projektordner und Verzeichnisstruktur anlegen

Lege einen dedizierten Ordner an und erstelle das Konfigurations-Unterverzeichnis. Dieser Schritt ist entscheidend: Docker legt beim Volume-Mount automatisch ein Verzeichnis an, wenn die Ziel-Datei noch nicht existiert – das verhindert, dass Gatus die Konfiguration lesen kann.

mkdir -p /opt/gatus/config
touch /opt/gatus/config/config.yaml
cd /opt/gatus

Die resultierende Verzeichnisstruktur sieht so aus:

/opt/gatus/
├── compose.yaml
├── .env
└── config/
    └── config.yaml

Verifizieren: ls -la /opt/gatus/config/ muss config.yaml als reguläre Datei (nicht als Verzeichnis) anzeigen. Der Typ in der ersten Spalte muss -rw sein, nicht drw.

Schritt 2: Secrets in der .env-Datei sichern

Secrets wie Webhook-URLs und Passwörter gehören nie direkt in die Konfigurationsdatei. Gatus löst alle ${VAR_NAME}-Referenzen in config.yaml automatisch aus Umgebungsvariablen auf – die .env-Datei im Projektordner ist der sichere Ablageort.

# /opt/gatus/.env
# Nur die Variablen eintragen, die du tatsächlich nutzt.
# Ungenutzte Zeilen können leer bleiben oder auskommentiert werden.

# Slack Alerting (optional)
SLACK_WEBHOOK_URL=https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX

# PagerDuty Alerting (optional)
PAGERDUTY_KEY=dein-pagerduty-integration-key

# E-Mail Alerting via SMTP (optional)
# Bei Gmail: App-Passwort verwenden, kein Account-Passwort!
SMTP_PASSWORD=dein-app-passwort

Danach unbedingt .env zur .gitignore hinzufügen, damit Secrets nicht ins Repository gelangen:

echo ".env" >> /opt/gatus/.gitignore

Verifizieren: cat /opt/gatus/.env zeigt die gesetzten Variablen. Prüfe, dass die Datei keine Leerzeichen um das =-Zeichen enthält, da Docker Compose diese Syntax nicht toleriert.

Schritt 3: Konfigurationsdatei config.yaml erstellen

Die gesamte Steuerung von Gatus erfolgt über config/config.yaml. Hier werden Storage, Web-Einstellungen, Alerting-Provider und die zu überwachenden Endpunkte definiert. Das folgende Beispiel enthält einen HTTP-Endpunkt mit Slack-Alerting, einen DNS-Check und einen ICMP-Ping – drei typische Monitoring-Szenarien.

Wichtig bei Bedingungen: Schreibe immer Leerzeichen um den Operator, also [STATUS] == 200 und nicht [STATUS]==200. Fehlende Leerzeichen führen dazu, dass Bedingungen stillschweigend als erfüllt gewertet werden.

# /opt/gatus/config/config.yaml

# ── Datenpersistenz (SQLite empfohlen für Einzel-Host) ──────────────────
storage:
  type: sqlite
  path: /data/gatus.db

# ── Web-Einstellungen ────────────────────────────────────────────────────
web:
  address: "0.0.0.0"
  port: 8080

# ── Alerting-Provider (nur konfigurieren, was du nutzt) ─────────────────
alerting:
  slack:
    webhook-url: "${SLACK_WEBHOOK_URL}"
    default-alert:
      failure-threshold: 3   # Alert nach 3 aufeinanderfolgenden Fehlern
      success-threshold: 2   # Entwarnung nach 2 Erfolgen

  pagerduty:
    integration-key: "${PAGERDUTY_KEY}"
    default-alert:
      failure-threshold: 5
      success-threshold: 3

  email:
    from: "gatus@example.com"
    username: "deine-email@gmail.com"
    password: "${SMTP_PASSWORD}"
    host: "smtp.gmail.com"
    port: 587
    to: "team@example.com"

# ── Zu überwachende Endpunkte ────────────────────────────────────────────
endpoints:
  - name: Meine API
    group: produktion
    url: "https://api.example.com/health"
    interval: 30s
    conditions:
      - "[STATUS] == 200"
      - "[RESPONSE_TIME] < 500"
      - "[CERTIFICATE_EXPIRATION] > 48h"
    alerts:
      - type: slack
        failure-threshold: 3
        success-threshold: 2

  - name: DNS-Check Google
    url: "8.8.8.8"
    interval: 5m
    dns:
      query-name: "example.com"
      query-type: "A"
    conditions:
      - "[DNS_RCODE] == NOERROR"

  - name: ICMP-Ping Gateway
    url: "icmp://192.168.1.1"
    interval: 1m
    conditions:
      - "[CONNECTED] == true"

Verifizieren: cat /opt/gatus/config/config.yaml – die Datei muss vollständig und korrekt eingerückt sein. YAML ist whitespace-sensitiv; Tabulatoren sind verboten, nur Leerzeichen verwenden.

Schritt 4: compose.yaml erstellen

Die folgende compose.yaml nutzt das offizielle GHCR-Image ghcr.io/twin/gatus:stable (empfohlen für deterministisches Verhalten gegenüber :latest), ein benanntes SQLite-Volume und einen eingebauten Healthcheck über den /health-Endpunkt.

Hinweis für ICMP-Monitoring: Wenn du icmp://-Endpunkte überwachen möchtest, benötigt der Container die NET_RAW-Capability. Füge dazu den Block cap_add: [NET_RAW] zum Service hinzu – ohne diese Capability schlägt jeder ICMP-Check mit „permission denied" fehl.

ParameterWertHinweis
Imageghcr.io/twin/gatus:stablev5.36.0; auch twinproduction/gatus:stable auf Docker Hub verfügbar
Port8080:8080Dashboard, REST-API, /health und /metrics
Config-Volume./config/config.yaml:/config/config.yaml:roRead-only-Mount empfohlen
Daten-Volumegatus-data:/dataSQLite-Persistenz; Pfad muss mit storage.path übereinstimmen
RAM (typisch)~40 MBFür 50 Endpunkte; sehr ressourcenschonend
Architekturamd64, arm64, arm/v7Läuft auf Intel/AMD, Raspberry Pi und ARM-Servern
# /opt/gatus/compose.yaml
services:
  gatus:
    container_name: gatus
    image: ghcr.io/twin/gatus:stable
    restart: unless-stopped
    ports:
      - "8080:8080"
    volumes:
      - ./config/config.yaml:/config/config.yaml:ro
      - gatus-data:/data
    environment:
      - GATUS_CONFIG_PATH=/config/config.yaml
      - GATUS_LOG_LEVEL=INFO
      - SLACK_WEBHOOK_URL=${SLACK_WEBHOOK_URL}
      - PAGERDUTY_KEY=${PAGERDUTY_KEY}
      - SMTP_PASSWORD=${SMTP_PASSWORD}
    # ICMP-Monitoring benötigt NET_RAW (auskommentiert lassen, wenn kein ICMP):
    # cap_add:
    #   - NET_RAW
    healthcheck:
      test: ["CMD", "wget", "-qO-", "http://localhost:8080/health"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 10s

volumes:
  gatus-data:

Verifizieren: docker compose config im Projektordner zeigt die zusammengeführte Konfiguration ohne Fehler. Alle ${VAR}-Variablen aus der .env werden dabei aufgelöst und angezeigt.

Schritt 5: Container starten

Jetzt ist alles vorbereitet. Starte Gatus im Hintergrund:

cd /opt/gatus
docker compose up -d

Docker lädt das Image (~24 MB komprimiert) herunter, erstellt das benannte Volume gatus-data und startet den Container. Nach etwa 10 Sekunden (Start-Periode des Healthchecks) sollte der Container als healthy laufen.

Verifizieren:

# Container-Status prüfen – erwartete Ausgabe: STATUS = Up (healthy)
docker compose ps

# Logs auf Fehler prüfen – keine Fehlermeldungen zu Image/Port/Volume
docker compose logs gatus

# Health-Endpunkt direkt ansprechen – erwartete Ausgabe: {"status":"UP"}
curl -s http://localhost:8080/health

# Dashboard im Browser aufrufen
# http://localhost:8080

Die Logs sollten eine Zeile wie INFO Starting Gatus on port 8080 und danach die ersten Check-Ergebnisse zeigen. Erscheinen dort Meldungen wie no such file or directory für die Konfiguration, prüfe den Volume-Mount und ob config/config.yaml als Datei (nicht Verzeichnis) existiert.

Schritt 6: Alerting konfigurieren und testen

Das Alerting ist vollständig über config.yaml gesteuert. Die wichtigsten Provider sind bereits im Beispiel aus Schritt 3 enthalten. Für den Produktiveinsatz gilt:

  1. Slack: Webhook-URL aus der Slack-App-Verwaltung in .env als SLACK_WEBHOOK_URL eintragen. Die failure-threshold- und success-threshold-Werte verhindern Alert-Flooding bei kurzen Ausfällen (Flapping-Prevention).
  2. PagerDuty: Integration-Key aus dem PagerDuty-Service als PAGERDUTY_KEY in .env setzen.
  3. E-Mail via Gmail: Unbedingt ein App-Passwort (nicht das Google-Account-Passwort) verwenden, da Google den Zugriff über „weniger sichere Apps" abgeschaltet hat.

Um das Alerting ohne echten Ausfall zu testen, setze temporär eine Bedingung, die immer fehlschlägt:

conditions:
  - "[STATUS] == 999"   # Immer false – löst Alert aus

Danach Container neustarten und auf die Benachrichtigung warten:

docker compose restart gatus
docker compose logs -f gatus

Nach dem Test die Bedingung zurücksetzen und Container erneut neu starten. Wichtig: Gatus lädt die Konfiguration ausschließlich beim Start. Jede Änderung an config.yaml erfordert docker compose restart gatus.

Verifizieren: Nach dem Neustart zeigen die Logs, welche Endpunkte geprüft werden und ob Alerts ausgelöst werden (INFO Sending Slack alert o. ä.). Im Browser unter http://localhost:8080 erscheinen die Endpunkte mit ihrem aktuellen Status.

Schritt 7: Dashboard absichern und Updates einspielen

Basic-Auth für das Dashboard

Gatus bietet eingebaute HTTP-Basic-Authentifizierung. Das Passwort wird als bcrypt-Hash (Base64-kodiert) in config.yaml hinterlegt. Hash generieren:

docker run --rm httpd:alpine htpasswd -nbB admin 'meinPasswort' | cut -d':' -f2 | base64

Den ausgegebenen String in config.yaml unter security eintragen:

security:
  basic:
    username: "admin"
    password-bcrypt-base64: "JDJ5JDE2JGFiY2..."   # Ausgabe des obigen Befehls

Prometheus-Metriken aktivieren

Wer Gatus-Daten in Prometheus mit Alertmanager oder Grafana integrieren möchte, aktiviert den Metriken-Endpunkt mit einer einzigen Zeile in config.yaml:

metrics: true

Danach sind Metriken unter http://localhost:8080/metrics abrufbar.

Updates einspielen

cd /opt/gatus
docker compose pull
docker compose up -d

Docker lädt das neue :stable-Image und startet den Container neu. Das benannte Volume gatus-data bleibt dabei erhalten.

Verifizieren: Nach dem Update docker compose ps – Status muss Up (healthy) sein. docker image ls ghcr.io/twin/gatus zeigt das neue Image-Datum.

Troubleshooting / Typische Fehler

  1. „permission denied" bei ICMP-Checks: Der Container fehlt die Netzwerk-Capability. Lösung: cap_add: [NET_RAW] im gatus-Service in compose.yaml eintragen und Container neu starten.
  2. Gatus startet nicht, Logs zeigen „no such file or directory" für config.yaml: Docker hat beim ersten Mount ein Verzeichnis statt einer Datei angelegt. Lösung: docker compose down, das fehlerhafte Verzeichnis entfernen, Datei mit touch neu erstellen und Container neu starten.
  3. SQLite-Daten gehen nach Neustart verloren: Das Volume gatus-data:/data fehlt in compose.yaml oder storage.path in config.yaml zeigt auf einen anderen Pfad als /data/gatus.db. Volume-Mount und Pfad müssen identisch sein.
  4. Alerting funktioniert nicht, keine Logs: Bedingungssyntax prüfen – [STATUS] == 200 mit Leerzeichen um ==. Ohne Leerzeichen gilt die Bedingung immer als erfüllt und löst nie einen Alert aus.
  5. Gmail-SMTP schlägt fehl mit „Username and Password not accepted": Google blockiert reguläre Account-Passwörter. Ein App-Passwort in der Google-Konto-Verwaltung unter „Sicherheit → App-Passwörter" erstellen und in .env als SMTP_PASSWORD eintragen.
  6. „permission denied" beim Lesen von config.yaml auf Linux mit SELinux: Volume-Mount um das :z-Flag erweitern: ./config/config.yaml:/config/config.yaml:ro,z.
  7. Konfigurationsänderungen haben keine Wirkung: Gatus lädt die Konfiguration nur beim Start. Nach jeder Änderung an config.yaml ist docker compose restart gatus erforderlich.

Häufige Fragen

Brauche ich zwingend eine Datenbank?

Nein. Ohne storage-Block in config.yaml speichert Gatus alle Daten im Arbeitsspeicher. Das reicht für einfache Setups, aber nach einem Container-Neustart ist die gesamte Uptime-Historie weg. SQLite ist die empfohlene leichtgewichtige Alternative – ein einfaches benanntes Volume genügt, keine separate Datenbank-Infrastruktur nötig.

Kann ich mehrere Konfigurationsdateien nutzen?

Ja. Wenn GATUS_CONFIG_PATH auf ein Verzeichnis zeigt (z. B. /config), lädt Gatus automatisch alle *.yaml- und *.yml-Dateien und mergt sie. Arrays wie endpoints werden dabei angehängt, nicht überschrieben. Das ist ideal für GitOps-Workflows, bei denen Endpunkte pro Team oder Umgebung in separaten Dateien gepflegt werden.

Wie definiere ich Wartungsfenster, um Fehlalarme zu vermeiden?

Unter dem Endpunkt-Block kann ein maintenance-Schlüssel gesetzt werden mit start, duration und every. Während des definierten Fensters werden keine Alerts ausgelöst, auch wenn Checks fehlschlagen.

Wie viele Endpunkte kann Gatus gleichzeitig überwachen?

Das ist über den globalen Parameter concurrency (Standard: 3 parallele Checks) konfigurierbar. Bei vielen Endpunkten diesen Wert erhöhen. Die RAM-Nutzung bleibt auch bei großen Setups sehr gering – ~40 MB für 50 Endpunkte.

Wie unterscheidet sich Gatus von Uptime Kuma?

Uptime Kuma bietet eine grafische Oberfläche zur Konfiguration, Gatus arbeitet ausschließlich per YAML – was es besser für GitOps und automatisierte Deployments geeignet macht. Gatus unterstützt zudem mehr Protokolle (DNS, gRPC, SSH) und hat einen deutlich geringeren RAM-Verbrauch. Wer eine grafische Oberfläche bevorzugt, ist mit Beszel Server Monitoring gut beraten.

Fazit

Gatus ist die richtige Wahl, wenn du Monitoring-Konfigurationen versionieren, per GitOps ausrollen und mit minimalem Overhead betreiben willst. Der YAML-only-Ansatz ist für Entwickler und DevOps-Teams ein echter Vorteil – kein Browser-Klicken, kein Datenbankschema pflegen, einfach git push und docker compose restart. Die Kombination aus öffentlicher Statusseite und internem Monitoring in einem einzigen 24-MB-Container ist schwer zu übertreffen. Für umfangreichere Monitoring-Stacks mit Metriken und Dashboards lohnt sich die Integration mit cAdvisor und Prometheus – Gatus liefert dabei den /metrics-Endpunkt für den Prometheus-Scraper.

Weiterführende Anleitungen und Quellen

  1. Beszel Server Monitoring mit Docker einrichten – GUI-basiertes Monitoring als Alternative
  2. Prometheus Alerts an Telegram und Discord senden – Alertmanager für komplexere Alert-Routing-Logik
  3. cAdvisor mit Prometheus – Docker-Container-Metriken sammeln und in Grafana visualisieren
  4. Docker Compose absichern: Secrets, Healthchecks, Non-Root – Best Practices für den Produktivbetrieb

Offizielle Dokumentation und Quellcode: GitHub: TwiN/gatus · GHCR: ghcr.io/twin/gatus · Docker Hub: twinproduction/gatus

Passende Anleitungen auf S-EDV

  1. Prometheus node_exporter nativ installieren und als systemd-Dienst betreiben
  2. CVE-2022-0492: CISA warnt vor aktiv ausgenutztem Container-Escape im Linux-Kerne
  3. Docker und Docker Compose auf Linux installieren (Ubuntu/Debian): die Self-Hosti