← Alle Artikel
Zuletzt aktualisiert: 2026-03-30

Server-Monitoring einrichten: Wissen wenn der Server ausfällt

Uptime-Monitoring, Alerts und Prometheus + Grafana Stack einrichten. Kostenlose und kostenpflichtige Optionen.

Kurzfassung

Nutze kostenlose externe Monitoring-Dienste (UptimeRobot oder HetrixTools) für Erreichbarkeits-Checks und sofortige Benachrichtigungen. Für tiefere Einblicke in CPU, RAM, Festplatte und Container-Zustand setzt du Prometheus + Grafana per Docker Compose auf. Die Kombination beider Ansätze liefert umfassende Abdeckung: Externes Monitoring erkennt Ausfälle, die du von innerhalb deiner eigenen Infrastruktur nicht sehen kannst, während Prometheus dir die Metriken liefert, um Ursachen zu diagnostizieren und Probleme vorherzusagen, bevor sie auftreten.

Voraussetzungen

Was sollte überwacht werden

Bevor du irgendwelche Tools einrichtest, ist es wichtig zu verstehen, worauf es für die Server-Zuverlässigkeit ankommt:

Infrastruktur-Metriken

Anwendungs-Metriken

Schritt 1: Kostenlose Uptime-Überwachung

Externe Uptime-Monitore prüfen deinen Server von außerhalb deines Netzwerks. Das ist entscheidend, weil internes Monitoring netzwerkbedingte Ausfälle oder Routing-Probleme nicht erkennen kann, die Nutzer daran hindern, deinen Server zu erreichen.

UptimeRobot

UptimeRobot bietet im kostenlosen Plan 50 Monitore mit 5-Minuten-Intervallen.

  1. Erstelle ein Konto auf uptimerobot.com
  2. Klicke auf Add New Monitor
  3. Konfiguriere deinen ersten Monitor:

Füge weitere Monitore für kritische Endpunkte hinzu:

HetrixTools

HetrixTools bietet im kostenlosen Plan 15 Monitore mit 1-Minuten-Intervallen, plus eingebaute SSL- und Blacklist-Überwachung.

  1. Erstelle ein Konto auf hetrixtools.com
  2. Navigiere zu Uptime Monitors und klicke auf Add Monitor
  3. Wähle Website und gib deine URL ein
  4. Aktiviere SSL Certificate Monitoring — du wirst 30, 14 und 7 Tage vor Ablauf benachrichtigt
  5. Füge Monitoring-Standorte auf mehreren Kontinenten hinzu, um Ausfälle besser zu erkennen

Für die SSL-Ablaufüberwachung kannst du Zertifikate auch direkt über die Kommandozeile prüfen:

echo | openssl s_client -servername deinedomain.de -connect deinedomain.de:443 2>/dev/null | openssl x509 -noout -dates

Schritt 2: Prometheus + Grafana mit Docker Compose

Externe Monitore sagen dir, dass etwas ausgefallen ist. Prometheus und Grafana sagen dir warum und helfen dir, Probleme kommen zu sehen.

Verzeichnisstruktur

mkdir -p ~/monitoring/{prometheus,grafana,alertmanager}
cd ~/monitoring

Docker-Compose-Datei

Erstelle docker-compose.yml:

services:
  prometheus:
    image: prom/prometheus:v2.51.0
    container_name: prometheus
    restart: unless-stopped
    volumes:
      - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
      - ./prometheus/alert-rules.yml:/etc/prometheus/alert-rules.yml
      - prometheus_data:/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.retention.time=30d'
      - '--web.enable-lifecycle'
    ports:
      - "9090:9090"
    networks:
      - monitoring

  grafana:
    image: grafana/grafana:10.4.0
    container_name: grafana
    restart: unless-stopped
    volumes:
      - grafana_data:/var/lib/grafana
    environment:
      - GF_SECURITY_ADMIN_USER=admin
      - GF_SECURITY_ADMIN_PASSWORD=changeme_s3cure!
      - GF_USERS_ALLOW_SIGN_UP=false
    ports:
      - "3000:3000"
    networks:
      - monitoring

  node-exporter:
    image: prom/node-exporter:v1.7.0
    container_name: node-exporter
    restart: unless-stopped
    volumes:
      - /proc:/host/proc:ro
      - /sys:/host/sys:ro
      - /:/rootfs:ro
    command:
      - '--path.procfs=/host/proc'
      - '--path.rootfs=/rootfs'
      - '--path.sysfs=/host/sys'
      - '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)'
    ports:
      - "9100:9100"
    networks:
      - monitoring

  cadvisor:
    image: gcr.io/cadvisor/cadvisor:v0.49.1
    container_name: cadvisor
    restart: unless-stopped
    privileged: true
    volumes:
      - /:/rootfs:ro
      - /var/run:/var/run:ro
      - /sys:/sys:ro
      - /var/lib/docker/:/var/lib/docker:ro
      - /dev/disk/:/dev/disk:ro
    ports:
      - "8080:8080"
    networks:
      - monitoring

  alertmanager:
    image: prom/alertmanager:v0.27.0
    container_name: alertmanager
    restart: unless-stopped
    volumes:
      - ./alertmanager/alertmanager.yml:/etc/alertmanager/alertmanager.yml
    ports:
      - "9093:9093"
    networks:
      - monitoring

  blackbox-exporter:
    image: prom/blackbox-exporter:v0.25.0
    container_name: blackbox-exporter
    restart: unless-stopped
    ports:
      - "9115:9115"
    networks:
      - monitoring

volumes:
  prometheus_data:
  grafana_data:

networks:
  monitoring:
    driver: bridge

Prometheus-Konfiguration

Erstelle prometheus/prometheus.yml:

global:
  scrape_interval: 15s
  evaluation_interval: 15s

alerting:
  alertmanagers:
    - static_configs:
        - targets:
          - alertmanager:9093

rule_files:
  - "alert-rules.yml"

scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']

  - job_name: 'node-exporter'
    static_configs:
      - targets: ['node-exporter:9100']

  - job_name: 'cadvisor'
    static_configs:
      - targets: ['cadvisor:8080']

  - job_name: 'blackbox-http'
    metrics_path: /probe
    params:
      module: [http_2xx]
    static_configs:
      - targets:
        - https://deinedomain.de
        - https://api.deinedomain.de/health
    relabel_configs:
      - source_labels: [__address__]
        target_label: __param_target
      - source_labels: [__param_target]
        target_label: instance
      - target_label: __address__
        replacement: blackbox-exporter:9115

  - job_name: 'blackbox-ssl'
    metrics_path: /probe
    params:
      module: [http_2xx]
    static_configs:
      - targets:
        - https://deinedomain.de
    relabel_configs:
      - source_labels: [__address__]
        target_label: __param_target
      - source_labels: [__param_target]
        target_label: instance
      - target_label: __address__
        replacement: blackbox-exporter:9115

Alert-Regeln

Erstelle prometheus/alert-rules.yml:

groups:
  - name: server-alerts
    rules:
      - alert: HoheCpuAuslastung
        expr: 100 - (avg by(instance) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 80
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "Hohe CPU-Auslastung auf {{ $labels.instance }}"
          description: "CPU-Auslastung liegt seit über 5 Minuten über 80% (aktuell: {{ $value | printf \"%.1f\" }}%)"

      - alert: HoherSpeicherverbrauch
        expr: (1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100 > 85
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "Hoher Speicherverbrauch auf {{ $labels.instance }}"
          description: "Speicherverbrauch liegt über 85% (aktuell: {{ $value | printf \"%.1f\" }}%)"

      - alert: FestplatteKnapp
        expr: (1 - node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"}) * 100 > 85
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "Wenig Festplattenspeicher auf {{ $labels.instance }}"
          description: "Root-Dateisystem ist zu {{ $value | printf \"%.1f\" }}% belegt"

      - alert: ContainerAusgefallen
        expr: absent(container_last_seen{name=~".+"}) or (time() - container_last_seen{name=~".+"}) > 60
        for: 1m
        labels:
          severity: critical
        annotations:
          summary: "Container {{ $labels.name }} ist ausgefallen"

      - alert: EndpunktNichtErreichbar
        expr: probe_success == 0
        for: 2m
        labels:
          severity: critical
        annotations:
          summary: "Endpunkt {{ $labels.instance }} ist nicht erreichbar"
          description: "HTTP-Probe schlägt seit über 2 Minuten fehl"

      - alert: SslZertifikatLaeuftBaldAb
        expr: (probe_ssl_earliest_cert_expiry - time()) / 86400 < 14
        for: 1h
        labels:
          severity: warning
        annotations:
          summary: "SSL-Zertifikat für {{ $labels.instance }} läuft in {{ $value | printf \"%.0f\" }} Tagen ab"

Stack starten

cd ~/monitoring
docker compose up -d

# Prüfen, ob alle Container laufen
docker compose ps

# Prometheus-Targets prüfen
curl -s http://localhost:9090/api/v1/targets | jq '.data.activeTargets[] | {job: .labels.job, health: .health}'

Öffne Grafana unter http://deine-server-ip:3000, melde dich mit den Zugangsdaten aus der Compose-Datei an und füge Prometheus als Datenquelle mit der URL http://prometheus:9090 hinzu. Importiere Dashboard-ID 1860 (Node Exporter Full) und 14282 (cAdvisor) von grafana.com für fertige Visualisierungen.

Schritt 3: E-Mail- und Slack-Benachrichtigungen

Alertmanager-Konfiguration

Erstelle alertmanager/alertmanager.yml:

global:
  smtp_smarthost: 'smtp.gmail.com:587'
  smtp_from: 'alerts@deinedomain.de'
  smtp_auth_username: 'alerts@deinedomain.de'
  smtp_auth_password: 'dein-app-passwort'
  smtp_require_tls: true

route:
  group_by: ['alertname', 'severity']
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 4h
  receiver: 'email-slack'

  routes:
    - match:
        severity: critical
      receiver: 'email-slack'
      repeat_interval: 1h

receivers:
  - name: 'email-slack'
    email_configs:
      - to: 'admin@deinedomain.de'
        send_resolved: true
    slack_configs:
      - api_url: 'https://hooks.slack.com/services/DEIN/SLACK/WEBHOOK'
        channel: '#server-alerts'
        send_resolved: true
        title: '{{ if eq .Status "firing" }}ALARM{{ else }}BEHOBEN{{ end }}: {{ .CommonLabels.alertname }}'
        text: '{{ range .Alerts }}{{ .Annotations.description }}
{{ end }}'

Nach dem Erstellen der Datei starte den Alertmanager neu:

docker compose restart alertmanager

Benachrichtigungen testen

Prüfe, ob der Alertmanager Daten von Prometheus empfängt:

# Ausstehende und aktive Alerts prüfen
curl -s http://localhost:9093/api/v2/alerts | jq '.[].labels.alertname'

# Test-Alert senden
curl -X POST http://localhost:9093/api/v2/alerts \
  -H "Content-Type: application/json" \
  -d '[{"labels":{"alertname":"TestAlert","severity":"warning"},"annotations":{"summary":"Dies ist ein Test-Alert"},"startsAt":"'$(date -u +%Y-%m-%dT%H:%M:%S.000Z)'","generatorURL":"http://localhost:9090"}]'

Schritt 4: Docker Container Health Checks

Docker Health Checks teilen dem Daemon mit, ob ein Container tatsächlich funktioniert — nicht nur, ob er läuft. Füge sie zu deinen Anwendungs-Containern hinzu:

services:
  webapp:
    image: deine-app:latest
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    restart: unless-stopped

  database:
    image: postgres:16
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 30s
      timeout: 5s
      retries: 3
    restart: unless-stopped

  redis:
    image: redis:7-alpine
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 30s
      timeout: 5s
      retries: 3
    restart: unless-stopped

  nginx:
    image: nginx:alpine
    healthcheck:
      test: ["CMD-SHELL", "curl -f http://localhost/ || exit 1"]
      interval: 30s
      timeout: 5s
      retries: 3
    restart: unless-stopped

Health-Status über die Kommandozeile überwachen:

# Zustand aller Container prüfen
docker ps --format "table {{.Names}}\t{{.Status}}"

# Auf ungesunde Container warten
docker events --filter event=health_status

# Skript zur Benachrichtigung bei ungesunden Containern
#!/bin/bash
unhealthy=$(docker ps --filter health=unhealthy --format "{{.Names}}" 2>/dev/null)
if [ -n "$unhealthy" ]; then
  echo "UNGESUNDE Container: $unhealthy" | mail -s "Docker Health Alarm" admin@deinedomain.de
fi

Füge dieses Skript als Fallback zum Cron hinzu, falls dein Haupt-Monitoring selbst ausfällt:

# Alle 5 Minuten ausführen
*/5 * * * * /usr/local/bin/docker-health-check.sh

Schritt 5: Einfache Status-Seite

Eine öffentliche Status-Seite ermöglicht es Nutzern, die Dienstverfügbarkeit zu prüfen, ohne dich kontaktieren zu müssen. Sowohl UptimeRobot als auch HetrixTools bieten kostenlose gehostete Status-Seiten an.

UptimeRobot Status-Seite

  1. Gehe zu My Settings > Status Pages > Add Status Page
  2. Wähle die anzuzeigenden Monitore aus
  3. Passe das Design an dein Branding an
  4. Nutze die bereitgestellte URL oder richte einen CNAME-Eintrag ein (z.B. status.deinedomain.de)

Selbst gehostete Alternative: Gatus

Für eine selbst gehostete Status-Seite mit integriertem Monitoring füge Gatus zu deinem Stack hinzu:

  gatus:
    image: twinproduction/gatus:v5.11.0
    container_name: gatus
    restart: unless-stopped
    volumes:
      - ./gatus/config.yaml:/config/config.yaml
    ports:
      - "8081:8080"
    networks:
      - monitoring

Erstelle gatus/config.yaml:

storage:
  type: sqlite
  path: /data/data.db

endpoints:
  - name: Website
    url: https://deinedomain.de
    interval: 2m
    conditions:
      - "[STATUS] == 200"
      - "[RESPONSE_TIME] < 2000"
    alerts:
      - type: email
        send-on-resolved: true

  - name: API
    url: https://api.deinedomain.de/health
    interval: 1m
    conditions:
      - "[STATUS] == 200"
      - "[BODY].status == UP"
      - "[RESPONSE_TIME] < 1000"

  - name: SSL-Zertifikat
    url: https://deinedomain.de
    interval: 1h
    conditions:
      - "[CERTIFICATE_EXPIRATION] > 14d"

Fehlerbehebung

Prometheus zeigt Targets als DOWN an

# Prüfen, ob Exporter aus dem Docker-Netzwerk erreichbar sind
docker exec prometheus wget -qO- http://node-exporter:9100/metrics | head -5

# Container-Logs prüfen
docker logs node-exporter --tail 20

# Netzwerk-Konnektivität prüfen
docker network inspect monitoring_monitoring

Grafana kann Prometheus nicht erreichen

Beim Hinzufügen der Datenquelle verwende den Docker-Servicenamen http://prometheus:9090, nicht localhost. Beide Container müssen sich im selben Docker-Netzwerk befinden.

Alertmanager sendet keine E-Mails

# Alertmanager-Logs prüfen
docker logs alertmanager --tail 30

# Konfigurationssyntax überprüfen
docker exec alertmanager amtool check-config /etc/alertmanager/alertmanager.yml

# Für Gmail: Verwende ein App-Passwort, nicht dein normales Passwort
# Aktivieren unter https://myaccount.google.com/apppasswords

cAdvisor verbraucht viel CPU

Auf Systemen mit vielen Containern kann cAdvisor erhebliche Ressourcen verbrauchen. Schränke den Erfassungsbereich ein:

  cadvisor:
    command:
      - '--housekeeping_interval=30s'
      - '--docker_only=true'
      - '--disable_metrics=percpu,sched,tcp,udp,disk,diskIO,hugetlb,referenced_memory'

Festplatte füllt sich durch Prometheus-Daten

# Aktuelle Speichergröße prüfen
du -sh /var/lib/docker/volumes/monitoring_prometheus_data/_data/

# Aufbewahrungsdauer in docker-compose.yml reduzieren
# Ändere: --storage.tsdb.retention.time=30d
# Zu:     --storage.tsdb.retention.time=15d

# Prometheus neu starten
docker compose restart prometheus

Vorbeugung und Best Practices

Mehrschichtiger Monitoring-Ansatz

  1. Externes Uptime-Monitoring (UptimeRobot/HetrixTools) — erkennt Ausfälle, die für Endnutzer sichtbar sind
  2. Interne Metriken (Prometheus + Grafana) — liefert tiefe Einblicke in Ressourcenverbrauch und Trends
  3. Container Health Checks — ermöglicht Docker den automatischen Neustart ausgefallener Dienste
  4. Log-Monitoring — ergänze Loki oder leite Logs weiter, um Fehler auf Anwendungsebene zu erkennen

Alert-Hygiene

Sicherheitshinweise

Wartungsroutine

# Monatlich: Monitoring-Stack aktualisieren
cd ~/monitoring
docker compose pull
docker compose up -d

# Wöchentlich: Festplattenbelegung im Blick behalten
df -h / | tail -1

# Prüfen, ob alle Prometheus-Targets gesund sind
curl -s http://localhost:9090/api/v1/targets | jq '.data.activeTargets[] | select(.health != "up") | .labels.job'

Ein gut konfiguriertes Monitoring-Setup macht sich beim ersten Mal bezahlt, wenn es dich um 2 Uhr nachts weckt, anstatt dass deine Nutzer den Ausfall um 9 Uhr morgens entdecken. Starte noch heute mit den kostenlosen externen Tools und erweitere dann schrittweise um Prometheus und Grafana, wenn deine Infrastruktur wächst.

Experten-Hilfe gebraucht?

Monitoring + Alerts richtig einrichten? €49, in 30 Min erledigt.

Jetzt buchen — €49

100% Geld-zurück-Garantie

HR

Harald Roessler

Infrastructure Engineer mit 20+ Jahren Erfahrung. Gründer der DSNCON GmbH.