Zum Inhalt

Prometheus und Grafana per Docker installieren: Eigene Metrik-Überwachung für Server und Container

Veröffentlicht am 30. September 2026 · Geschätzte Lesezeit: 8 Minuten

Wo früher Bauchgefühl reichte, zeigen Zahlen, was der Server wirklich leistet. Prometheus sammelt Metriken von deinem System und deinen Containern, Grafana macht daraus übersichtliche Dashboards im Browser. Der gesamte Stack läuft als Docker-Compose-Setup und braucht etwa 30–45 Minuten Einrichtungszeit.[1][2]

Voraussetzungen

  • Ein Linux-Server mit Docker und Docker Compose
  • Ein Benutzerkonto mit Docker-Berechtigung
  • Port 9090 (Prometheus), 3000 (Grafana) und 8080 (cAdvisor) im Heimnetz frei
  • Etwa 1 GB freier Arbeitsspeicher zusätzlich zu deinen Containern
  • Grundlegendes Verständnis von Docker Compose

1. Arbeitsordner anlegen

Erstelle einen Projektordner und wechsle hinein. Hier liegen später alle Konfigurationsdateien.[1]

mkdir -p ~/docker/monitoring && cd ~/docker/monitoring

2. Prometheus-Konfiguration erstellen

Prometheus braucht eine Konfigurationsdatei, die festlegt, welche Dienste es auslesen soll (sogenannte Targets). Erstelle prometheus.yml im Projektordner:[1]

global:
  scrape_interval: 15s       # Alle 15 Sekunden Metriken abholen
  evaluation_interval: 15s   # Alle 15 Sekunden Regeln auswerten

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"]

Was passiert hier? Drei Jobs sammeln Metriken: Prometheus überwacht sich selbst, Node Exporter misst den Host (CPU, RAM, Festplatte), cAdvisor misst die Docker-Container. Die Dienstnamen wie node_exporter:9100 werden später von Docker Compose im internen Netzwerk aufgelöst.[1][5]

3. Docker-Compose-Datei anlegen

Erstelle compose.yaml im Projektordner. Dieses Setup startet vier Dienste in einem gemeinsamen Netzwerk: Prometheus, Node Exporter, cAdvisor und Grafana.[8]

services:
  prometheus:
    image: prom/prometheus:v3.5.3
    container_name: prometheus
    restart: unless-stopped
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
      - prometheus_data:/prometheus
    command:
      - "--config.file=/etc/prometheus/prometheus.yml"
      - "--storage.tsdb.path=/prometheus"
      - "--web.console.libraries=/etc/prometheus/console_libraries"
      - "--web.console.templates=/etc/prometheus/consoles"
      - "--web.enable-lifecycle"
    expose:
      - "9090"

  node_exporter:
    image: prom/node-exporter:v1.12.1
    container_name: node_exporter
    restart: unless-stopped
    network_mode: "host"
    pid: "host"
    volumes:
      - "/:/host:ro,rslave"
    command:
      - "--path.rootfs=/host"

  cadvisor:
    image: gcr.io/cadvisor/cadvisor:v0.55.1
    container_name: cadvisor
    restart: unless-stopped
    privileged: true
    devices:
      - /dev/kmsg
    volumes:
      - "/:/rootfs:ro"
      - "/var/run:/var/run:ro"
      - "/sys:/sys:ro"
      - "/var/lib/docker/:/var/lib/docker:ro"
      - "/dev/disk:/dev/disk:ro"
    expose:
      - "8080"

  grafana:
    image: grafana/grafana:13.2.2
    container_name: grafana
    restart: unless-stopped
    environment:
      GF_SECURITY_ADMIN_PASSWORD: "<admin-passwort>"   # Ersetze diesen Platzhalter durch ein sicheres Passwort deiner Wahl
    volumes:
      - grafana_data:/var/lib/grafana
    ports:
      - "3000:3000"
    depends_on:
      - prometheus

volumes:
  prometheus_data:
  grafana_data:

Erklärung der Komponenten:

  • prometheus – Der Metrik-Speicher. Liest die Konfiguration aus der erstellten prometheus.yml, speichert alle Messdaten im Docker-Volume prometheus_data und erlaubt das Neuladen der Konfiguration per API (--web.enable-lifecycle).[1]
  • node_exporter – Der Host-Monitor. Läuft im Host-Netzwerk (network_mode: host), sieht deshalb die echten Systemmetriken und misst den Server selbst, nicht den Container.[4]
  • cadvisor – Der Container-Monitor. Beobachtet alle laufenden Docker-Container und sammelt CPU-, RAM-, Netzwerk- und Festplatten-Metriken pro Container.[3]
  • grafana – Die Dashboard-Oberfläche. Zeigt die Daten aus Prometheus als Diagramme und Tabellen an. Die Umgebungsvariable GF_SECURITY_ADMIN_PASSWORD setzt das Admin-Passwort beim ersten Start. Ersetze den Platzhalter <admin-passwort> durch ein eigenes, sicheres Passwort.[2]

Versionen prüfen und ersetzen

Die genannten Versionen (Prometheus v3.5.3, Node Exporter v1.12.1, cAdvisor v0.55.1, Grafana 13.2.2) waren zum Zeitpunkt dieser Anleitung aktuell. Prüfe vor dem Start die aktuell stable Version auf Docker Hub oder GitHub und ersetze die Tags bei Bedarf. Ein fester Versionstag ist immer besser als latest, weil ein Update dein Setup nicht unerwartet verändern kann.[5]

GF_SECURITY_ADMIN_PASSWORD im Klartext

Das Admin-Passwort steht in dieser Compose-Datei als Klartext-Umgebungsvariable. Für den Heimgebrauch ist das vertretbar, solange Grafana nur im Heimnetz erreichbar ist. In einer produktiven Umgebung solltest du Docker Secrets verwenden oder das Passwort über eine .env-Datei referenzieren (siehe docker-compose-secrets.md).

4. Stack starten

Prüfe zunächst die Compose-Datei auf Syntaxfehler:

docker compose config

Wenn keine Fehlermeldung erscheint, startest du alle Dienste:

docker compose up -d

Warte etwa 30 Sekunden und kontrolliere den Zustand:

docker compose ps

Alle vier Container sollten den Status Up zeigen.

5. Prometheus-Targets prüfen

Öffne die Prometheus-Weboberfläche unter http://<server-ip>:9090/targets (ersetze <server-ip> durch die IP deines Docker-Servers, z. B. 192.168.1.100).

Prometheus Targets

Alle drei Targets (prometheus, node_exporter, cadvisor) müssen den Status UP (grün) anzeigen. Ist ein Target rot, hat Prometheus keine Verbindung – dann Prüfschritt 10 beachten.[1]

6. Grafana-Datenquelle einrichten

Öffne Grafana im Browser: http://<server-ip>:3000. Melde dich mit admin und dem von dir in der Compose-Datei gesetzten Passwort an.

Gehe zu Connections → Add new connection, suche Prometheus und trage als URL http://prometheus:9090 ein. Klicke auf Save & test. Grafana muss die Verbindung als erfolgreich bestätigen.[2]

Standard-Passwort geändert?

Wenn du GF_SECURITY_ADMIN_PASSWORD nicht gesetzt hast, lauten die Standard-Anmeldedaten admin / admin. Ändere das Passwort sofort nach der ersten Anmeldung.

7. Erstes Dashboard importieren

Der einfachste Weg zu einer aussagekräftigen Ansicht ist der Import eines vorgefertigten Dashboards:[6][7]

  1. Klicke links auf das Dashboard-Menü (Symbol mit den vier Quadraten) → Import
  2. Gib eine der folgenden Dashboard-IDs ein:
  3. 1860 – Node Exporter Full (zeigt Host-CPU, RAM, Festplatte, Netzwerk)[6]
  4. 16310 – Docker and System Monitoring (kombiniert Host- und Container-Ansichten)[7]
  5. Klicke auf Load, wähle als Datenquelle Prometheus aus und bestätige mit Import

Jetzt siehst du die ersten Diagramme. Sind alle Graphen leer, warte eine Minute – Prometheus sammelt die Daten erst nach dem Start.

8. PromQL-Explorer testen

Wechsle zu Explore (Menü links, Balken-Diagramm-Symbol). Wähle als Datenquelle Prometheus und gib folgende Abfragen ein:

100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)

Erklärung – CPU-Auslastung aller Kerne in Prozent, gemittelt über die letzten 5 Minuten.

(1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100

Erklärung – Arbeitsspeicher-Nutzung in Prozent.

rate(container_cpu_usage_seconds_total{name="prometheus"}[1m])

Erklärung – CPU-Nutzung eines bestimmten Containers (hier: prometheus).

Jede Abfrage sollte eine Zeitreihe zurückgeben. Ist ein Wert dauerhaft 0 oder fehlt, stimmt etwas mit der Datenquelle oder dem Target nicht.

9. Backup und Rückweg

Der gesamte Konfigurationsordner ist schnell gesichert:

cd ~/docker/monitoring
tar -czf monitoring-backup-2026-09-30.tar.gz compose.yaml prometheus.yml

Die eigentlichen Metrik-Daten liegen in den Docker-Volumes prometheus_data und grafana_data. Ein Volume-Backup erstellst du mit:

docker run --rm -v prometheus_data:/source -v $(pwd):/backup alpine \
  tar czf /backup/prometheus_data_2026-09-30.tar.gz -C /source .

docker run --rm -v grafana_data:/source -v $(pwd):/backup alpine \
  tar czf /backup/grafana_data_2026-09-30.tar.gz -C /source .

Datenvolumen kann sehr groß sein

Prometheus-Daten können bei langer Laufzeit mehrere Gigabyte groß sein. Das Einlesen des gesamten Volumes in ein Archiv dauert entsprechend.

Zum kompletten Entfernen aller Dienste inklusive Daten:

docker compose down -v

Ohne -v bleiben die Volumes erhalten und die Daten sind beim nächsten docker compose up -d wieder da.

Risiken und wichtige Hinweise

  1. Keine Authentifizierung in Prometheus und cAdvisor – Beide Dienste haben kein eigenes Login. Setze sie niemals direkt per Router-Portfreigabe ins Internet. Verwende stattdessen einen Reverse Proxy mit Authentifizierung (siehe caddy-https-docker.md) oder ein VPN (siehe tailscale-server-zugriff.md).[1]
  2. cAdvisor läuft privilegiert – Der Container benötigt privileged: true und Zugriff auf /dev/kmsg, um Container-Metriken korrekt zu erfassen. Das ist für das Heimnetz akzeptabel, aber ein zusätzliches Risiko, falls ein Angreifer den Container übernehmen sollte.[3]
  3. Grafana-Enterprise ist der neue Standard – Seit Februar 2026 empfiehlt Grafana die Enterprise-Edition als Standard-Docker-Image. Die OSS-only-Variante grafana/grafana-oss wird nicht mehr aktiv weiterentwickelt. Die Enterprise-Edition ist für den Heimgebrauch kostenlos und funktionsgleich mit der OSS-Version.[2]
  4. Speicherverbrauch – Prometheus und Grafana zusammen benötigen je nach Datenmenge etwa 500 MB bis 1 GB RAM. Bei vielen Targets oder langen Laufzeiten wächst das Prometheus-Daten-Volume (prometheus_data) auf mehrere GB an. Der Node Exporter und cAdvisor sind mit je ca. 50 MB RAM sehr leicht.

Typische Fehler

  1. Grafana-Datenquelle auf localhost:9090 gesetzt. localhost im Grafana-Container ist der Grafana-Container selbst. Die URL muss http://prometheus:9090 lauten.
  2. Node Exporter ohne pid: "host" und --path.rootfs=/host. Ohne diese Einstellungen misst Node Exporter nur sich selbst, nicht den Host.
  3. latest-Tag statt festem Versionstag. Ein docker compose pull kann das Image unerwartet wechseln und Metrik-Format oder Dashboard-Labels brechen. Verwende immer einen festen Tag.
  4. Ports direkt exposen, obwohl kein Auth existiert. Verwende expose: für Prometheus und cAdvisor (nur intern im Docker-Netzwerk erreichbar). Nur Grafana braucht ports: für den Browser-Zugriff.
  5. cAdvisor ohne /dev/kmsg. Dann fehlen OOM-Metriken und cAdvisor gibt Start-Warnungen aus.

Fertig

Prometheus, Grafana, Node Exporter und cAdvisor laufen nun unter diesen Adressen:

  • Prometheus-UI: http://<server-ip>:9090
  • Grafana-Dashboard: http://<server-ip>:3000
  • cAdvisor-UI: http://<server-ip>:8080

Führe zum Abschluss diese Funktionsprüfung aus:

echo "=== Funktionsprüfung ==="

echo -n "1. Prometheus-Targets alle UP: "
curl -sf http://localhost:9090/api/v1/targets | python3 -c "
import sys,json
data = json.load(sys.stdin)
targets = data['data']['activeTargets']
up = all(t['health'] == 'up' for t in targets)
print('OK' if up else 'FEHLER')
" 2>/dev/null || echo "FEHLER"

echo -n "2. Grafana-Health: "
curl -sf http://localhost:3000/api/health | python3 -c "
import sys,json
d = json.load(sys.stdin)
print('OK -', d.get('message',''))
" 2>/dev/null || echo "FEHLER"

echo -n "3. Metriken in Prometheus vorhanden: "
curl -sf 'http://localhost:9090/api/v1/query?query=up' | python3 -c "
import sys,json
data = json.load(sys.stdin)
results = data['data']['result']
print(f'OK - {len(results)} Targets gemeldet')
" 2>/dev/null || echo "FEHLER"

echo -n "4. Container-Metriken via cAdvisor: "
curl -sf http://localhost:8080/api/v1.0/docker | python3 -c "
import sys,json
data = json.load(sys.stdin)
count = len(data)
print(f'OK - {count} Container gefunden')
" 2>/dev/null || echo "FEHLER"

Wenn alle vier Tests grün leuchten, läuft dein Monitoring-Stack. Öffne Grafana, öffne das importierte Dashboard und sieh dir die Live-Metriken deines Servers an. Die Daten sammeln sich ab jetzt automatisch – ohne dass du dich darum kümmern musst.

Sources: [1] https://prometheus.io/docs/prometheus/latest/installation/ — Prometheus Docker-Installation: Targets, Konfiguration und Web-UI [2] https://grafana.com/docs/grafana/latest/setup-grafana/installation/docker/ — Grafana Docker-Installation und Datenquellen [3] https://github.com/google/cadvisor — cAdvisor: Container-Metriken, Docker-Volume-Mounts und privilegierter Modus [4] https://hub.docker.com/r/prom/node-exporter — Node Exporter Docker-Image: Host-Metriken, --path.rootfs und pid: host [5] https://jacar.es/en/node-exporter-and-cadvisor-with-docker/ — Praxis-Guide mit getesteten Versionen (v1.12.1, v0.60.5) und Sicherheitshinweisen [6] https://grafana.com/grafana/dashboards/1860 — Node Exporter Full Dashboard (Dashboard-ID 1860) [7] https://grafana.com/grafana/dashboards/16310 — Docker and System Monitoring Dashboard (Dashboard-ID 16310) [8] https://github.com/docker/awesome-compose/blob/master/prometheus-grafana/README.md — Docker-offizielles Compose-Beispiel für Prometheus und Grafana