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

Prometheus mit Docker installieren: Monitoring-Stack mit Grafana und Alertmanager

Prometheus v3.12.0 per Docker Compose aufsetzen – mit Grafana, Alertmanager und Node Exporter. Pull-Modell, PromQL, persistente TSDB: der komplette Monitoring-Stack in unter 20 Minuten betriebsbereit.

Prometheus mit Docker installieren: Monitoring-Stack mit Grafana und Alertmanager KI-generiert

Prometheus ist seit seiner Entstehung 2012 bei SoundCloud zum De-facto-Standard für das Monitoring von Cloud-Native-Infrastrukturen geworden – und das nicht ohne Grund. Als zweites Projekt nach Kubernetes in die Cloud Native Computing Foundation (CNCF) aufgenommen, kombiniert es ein elegantes Pull-Modell, bei dem Metriken aktiv von Endpunkten abgeholt werden, mit einer leistungsstarken Abfragesprache namens PromQL und einer hochoptimierten lokalen Zeitreihendatenbank. Wer Microservices, Container, VMs oder physische Server überwachen will, kommt an Prometheus kaum vorbei. Diese Anleitung richtet sich an DevOps-Teams, Platform-Engineers und ambitionierte Selfhoster, die den kompletten Monitoring-Stack – Prometheus, Grafana, Alertmanager und Node Exporter – per Docker Compose auf einem beliebigen Linux-Host aufsetzen wollen.

Voraussetzungen

  1. Linux-Host, VM oder NAS mit Docker Engine 20.10+ und dem Docker Compose Plugin v2 (docker compose-Befehl). Noch nicht installiert? Siehe Docker und Docker Compose auf Linux installieren.
  2. Mindestens 2 GB RAM (empfohlen: 4 GB für größere Umgebungen mit vielen Targets)
  3. Mindestens 20 GB freier Speicherplatz auf einem lokalen Dateisystem – kein NFS, kein AWS EFS (TSDB-Pflicht)
  4. Netzwerkzugang zu Port 9090 (Prometheus), 3000 (Grafana) und 9093 (Alertmanager) vom Browser aus
  5. Optional: Reverse Proxy mit TLS (nginx, Traefik, Caddy) für den Produktivbetrieb – Prometheus selbst hat keine eingebaute Authentifizierung

Schritt 1: Eckdaten und Projektordner anlegen

Bevor du mit den Konfigurationsdateien beginnst, ein Blick auf die Eckdaten des Stacks:

KomponenteImagePortZweck
Prometheusprom/prometheus:v3.12.09090Metriken-Sammlung, TSDB, PromQL
Node Exporterprom/node-exporter:v1.7.09100Host-Metriken (CPU, RAM, Disk, Netzwerk)
Alertmanagerprom/alertmanager:v0.27.09093Alert-Routing zu E-Mail, Slack, PagerDuty
Grafanagrafana/grafana:10.4.03000Dashboards und Visualisierung
Volume / Bind-MountZweck
prometheus_data (named)Persistente TSDB-Daten
grafana_data (named)Grafana-Einstellungen und Dashboards
./prometheus/prometheus.ymlPflicht-Konfiguration (scrape_configs)
./alertmanager/alertmanager.ymlAlert-Routing und Receiver
./grafana/provisioningAutomatische Datasource-Konfiguration

Lege die Ordnerstruktur an:

mkdir -p /opt/prometheus/{prometheus,alertmanager,grafana/provisioning/datasources}
cd /opt/prometheus

Verifizieren: ls /opt/prometheus sollte die Unterordner prometheus, alertmanager und grafana anzeigen.

Schritt 2: .env-Datei anlegen

Prometheus selbst benötigt keine Umgebungsvariablen – seine Konfiguration erfolgt ausschließlich über prometheus.yml und Command-Line-Flags. Grafana hingegen erwartet ein Admin-Passwort:

# /opt/prometheus/.env

# Grafana Admin-Zugang (Pflicht!)
GRAFANA_ADMIN_USER=admin
GRAFANA_ADMIN_PASSWORD=SicheresPasswortHierEintragen

# Optionale Port-Anpassungen
PROMETHEUS_PORT=9090
ALERTMANAGER_PORT=9093
GRAFANA_PORT=3000

# Retention (Standard 15 Tage, anpassbar z. B. auf 30d oder 90d)
PROMETHEUS_RETENTION=15d

Setze restriktive Berechtigungen, damit das Passwort nicht für alle Nutzer lesbar ist:

chmod 600 /opt/prometheus/.env

Verifizieren: ls -la /opt/prometheus/.env – die Ausgabe muss -rw------- zeigen. Kein anderer Nutzer darf das Passwort lesen.

Schritt 3: prometheus.yml erstellen

Die Konfigurationsdatei definiert, welche Targets Prometheus scrapt und wie lange er auf Antwort wartet. Wichtig: Prometheus lädt diese Datei beim Start und kann sie ohne Neustart neu laden (mehr dazu in den FAQ).

# /opt/prometheus/prometheus/prometheus.yml

global:
  scrape_interval: 15s       # Alle 15 Sekunden Metriken abrufen
  evaluation_interval: 15s   # Alerting-Regeln alle 15 Sekunden auswerten

alerting:
  alertmanagers:
    - static_configs:
        - targets:
            - alertmanager:9093   # Docker-interner DNS-Name

rule_files:
  # Hier koennen spaeter Alert-Regeln eingebunden werden:
  # - /etc/prometheus/rules/*.yml

scrape_configs:
  # Prometheus scrapt sich selbst
  - job_name: "prometheus"
    static_configs:
      - targets: ["localhost:9090"]

  # Node Exporter: Host-Metriken
  - job_name: "node-exporter"
    static_configs:
      - targets: ["node-exporter:9100"]   # Service-Name als DNS

Verifizieren: Prüfe die YAML-Syntax lokal:

docker run --rm \
  -v /opt/prometheus/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml \
  prom/prometheus:v3.12.0 \
  promtool check config /etc/prometheus/prometheus.yml

Die Ausgabe sollte SUCCESS: 1 file(s) found, 0 error(s) lauten.

Schritt 4: alertmanager.yml erstellen

Für den ersten Start genügt eine Minimal-Konfiguration, die eingehende Alerts empfängt und im Null-Receiver verwirft. Im Produktiveinsatz trägst du hier E-Mail, Slack oder PagerDuty ein – das zeigt Prometheus Alerts an Telegram und Discord senden: Alertmanager konfigurieren.

# /opt/prometheus/alertmanager/alertmanager.yml

route:
  receiver: "null"
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 12h

receivers:
  - name: "null"

Verifizieren: cat /opt/prometheus/alertmanager/alertmanager.yml muss die Datei fehlerfrei ausgeben. Ein komplett leerer receivers-Block führt beim Start zu einem Fehler.

Schritt 5: Grafana-Datasource automatisch bereitstellen

Damit Grafana beim ersten Start Prometheus direkt als Datenquelle kennt, nutzt du das Provisioning-System. Entscheidend: Die URL muss http://prometheus:9090 lauten – der Docker-interne DNS-Name des Services. http://localhost:9090 würde im Grafana-Container auf sich selbst zeigen und keine Daten liefern.

# /opt/prometheus/grafana/provisioning/datasources/prometheus.yml

apiVersion: 1

datasources:
  - name: Prometheus
    type: prometheus
    access: proxy
    url: http://prometheus:9090
    isDefault: true
    editable: true

Verifizieren: ls /opt/prometheus/grafana/provisioning/datasources/ – die Datei prometheus.yml muss vorhanden sein.

Schritt 6: compose.yaml erstellen und Stack starten

Jetzt kommt das Herzstück – die compose.yaml. Beachte: Wir verwenden explizite Versionstags (v3.12.0, v1.7.0, v0.27.0, 10.4.0) statt latest, um unerwartete Breaking Changes bei Updates zu vermeiden. Prometheus v3.x ist die aktuelle stabile Generation – v2.x erhält keinen Long-Term-Support mehr.

# /opt/prometheus/compose.yaml

services:
  prometheus:
    image: prom/prometheus:v3.12.0
    container_name: prometheus
    restart: unless-stopped
    ports:
      - "${PROMETHEUS_PORT:-9090}:9090"
    volumes:
      - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
      - prometheus_data:/prometheus
    command:
      - "--config.file=/etc/prometheus/prometheus.yml"
      - "--storage.tsdb.path=/prometheus"
      - "--storage.tsdb.retention.time=${PROMETHEUS_RETENTION:-15d}"
      - "--storage.tsdb.wal-compression"
      - "--web.enable-lifecycle"
      - "--web.console.libraries=/etc/prometheus/console_libraries"
      - "--web.console.templates=/etc/prometheus/consoles"
    depends_on:
      - node-exporter

  node-exporter:
    image: prom/node-exporter:v1.7.0
    container_name: node-exporter
    restart: unless-stopped
    ports:
      - "9100:9100"
    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)($$|/)"

  alertmanager:
    image: prom/alertmanager:v0.27.0
    container_name: alertmanager
    restart: unless-stopped
    ports:
      - "${ALERTMANAGER_PORT:-9093}:9093"
    volumes:
      - ./alertmanager/alertmanager.yml:/etc/alertmanager/alertmanager.yml:ro
    command:
      - "--config.file=/etc/alertmanager/alertmanager.yml"

  grafana:
    image: grafana/grafana:10.4.0
    container_name: grafana
    restart: unless-stopped
    ports:
      - "${GRAFANA_PORT:-3000}:3000"
    volumes:
      - grafana_data:/var/lib/grafana
      - ./grafana/provisioning:/etc/grafana/provisioning:ro
    environment:
      - GF_SECURITY_ADMIN_USER=${GRAFANA_ADMIN_USER:-admin}
      - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_ADMIN_PASSWORD:?Bitte GRAFANA_ADMIN_PASSWORD in .env setzen}
    depends_on:
      - prometheus

volumes:
  prometheus_data:
  grafana_data:

Starte den Stack:

cd /opt/prometheus
docker compose up -d

Docker lädt die Images herunter und startet alle vier Container. Beim ersten Start kann das je nach Internetverbindung 1–3 Minuten dauern.

Verifizieren: Prüfe den Status aller Container:

docker compose ps

Erwartete Ausgabe (alle vier Container mit Status Up):

NAME             IMAGE                          STATUS          PORTS
alertmanager     prom/alertmanager:v0.27.0      Up              0.0.0.0:9093->9093/tcp
grafana          grafana/grafana:10.4.0         Up              0.0.0.0:3000->3000/tcp
node-exporter    prom/node-exporter:v1.7.0      Up              0.0.0.0:9100->9100/tcp
prometheus       prom/prometheus:v3.12.0        Up              0.0.0.0:9090->9090/tcp

Prüfe zusätzlich die Health-Endpunkte:

curl -s http://localhost:9090/-/healthy   # Erwartet: Prometheus Server is Healthy.
curl -s http://localhost:9093/-/healthy   # Erwartet: OK
curl -I http://localhost:3000/            # Erwartet: HTTP/1.1 200 OK oder 302

Bei Problemen: docker compose logs prometheus bzw. docker compose logs grafana zeigt die genauen Fehlermeldungen.

Schritt 7: Prometheus Web-UI und Grafana einrichten

Öffne http://<deine-server-ip>:9090 im Browser. In der Prometheus Web-UI siehst du unter Status → Targets deine konfigurierten Scrape-Targets. Beide – prometheus und node-exporter – sollten den Status UP zeigen.

Teste eine erste PromQL-Abfrage: Gib im Expression-Feld up ein und klicke auf „Execute". Du siehst Zeitreihen mit dem Wert 1 für jeden laufenden Target – ein klares Zeichen, dass Prometheus Metriken sammelt.

Für Grafana rufst du http://<deine-server-ip>:3000 auf. Melde dich mit dem in der .env gesetzten Admin-Passwort an. Die Prometheus-Datenquelle ist dank Provisioning bereits eingebunden. Navigiere zu Connections → Data sources und überprüfe, ob „Prometheus" als Standard-Quelle aufgeführt ist.

Für einen sofortigen Mehrwert importierst du das bewährte Node Exporter Full Dashboard: Dashboards → New → Import, Dashboard-ID 1860 eingeben, Prometheus als Datenquelle auswählen und importieren. Du siehst sofort CPU-Last, RAM-Nutzung, Disk-I/O und Netzwerkdurchsatz deines Hosts in Echtzeit. Wie du eigene Panels und Dashboards aufbaust, erklärt Grafana-Dashboards bauen – von der Datenquelle zum Panel.

Container-Metriken für deinen Docker-Host ergänzt du mit cAdvisor – wie das geht, zeigt cAdvisor mit Prometheus: Docker-Container-Metriken sammeln und in Grafana visualisieren.

Verifizieren: In Grafana unter Connections → Data sources → Prometheus → „Test" muss „Data source is working" erscheinen. Unter Prometheus Status → Targets müssen beide Targets den State UP zeigen. Falls node-exporter auf DOWN steht, prüfe mit docker compose logs node-exporter auf Fehlermeldungen.

Schritt 8: Stack aktualisieren und Backup

Um den Stack auf neue Image-Versionen zu aktualisieren, passe zunächst die Tags in der compose.yaml an und führe dann aus:

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

Docker Compose startet nur die Container neu, deren Image sich geändert hat. Die persistenten Daten in den benannten Volumes prometheus_data und grafana_data bleiben dabei erhalten.

Für ein Backup genügt es, den /opt/prometheus-Ordner (Konfigurationsdateien + .env) zu sichern. Die TSDB-Daten in prometheus_data sind bei Verlust rekonstruierbar, da Prometheus die Targets erneut scrapt. Grafana-Dashboards und -Einstellungen in grafana_data solltest du jedoch regelmäßig exportieren oder das Volume in dein Backup einschließen – eine solide Strategie dazu liefert 3-2-1-Backup-Strategie umsetzen.

Verifizieren: Nach dem Update erneut docker compose ps ausführen – alle Container müssen wieder mit Status Up laufen. Mit curl -s http://localhost:9090/api/v1/status/buildinfo | grep version lässt sich die laufende Prometheus-Version bestätigen.

Troubleshooting / Typische Fehler

  1. „no such file or directory" beim Start / 0 Targets: Die prometheus.yml ist nicht korrekt gemountet. Prüfe den Pfad in compose.yaml und stelle sicher, dass die Datei unter ./prometheus/prometheus.yml relativ zum Projektordner existiert. Mit docker compose logs prometheus siehst du die genaue Fehlermeldung.
  2. „405 Method Not Allowed" bei POST /-/reload: Das Flag --web.enable-lifecycle fehlt in der command-Sektion der compose.yaml. Füge es hinzu und starte Prometheus neu.
  3. Grafana zeigt „No Data" trotz laufender Targets: Die häufigste Ursache ist eine falsche Datasource-URL. Öffne Connections → Data sources → Prometheus und stelle sicher, dass die URL http://prometheus:9090 lautet – nicht http://localhost:9090. Außerdem: Stimmt der Zeitbereich im Dashboard-Panel mit den tatsächlich vorhandenen Daten überein?
  4. Node Exporter bleibt auf DOWN: Auf manchen gehärteten Systemen fehlen die Berechtigungen für /proc- und /sys-Mounts. Prüfe mit docker compose logs node-exporter. Falls --path.procfs-Fehler erscheinen, kann der Container im privilegierten Modus gestartet werden.
  5. TSDB-Datenverlust nach Neustart: Prüfe mit docker volume ls, ob die Volumes prometheus_prometheus_data und prometheus_grafana_data angelegt wurden. Bind-Mounts auf Verzeichnisse, die dem falschen Nutzer gehören (Prometheus läuft als UID 65534), können zu Permission-Problemen führen – benannte Volumes vermeiden das.
  6. Port 9090 nicht erreichbar: Firewall prüfen. Auf UFW-Systemen: sudo ufw allow 9090/tcp. Ports 9090 und 9100 sollten generell nicht öffentlich exponiert werden, da Prometheus keine eingebaute Authentifizierung hat.
  7. Alertmanager empfängt keine Alerts: Prüfe, ob in prometheus.yml unter alerting.alertmanagers der korrekte Service-Name alertmanager:9093 eingetragen ist und ob rule_files auf existierende Dateien zeigen.

Häufige Fragen

Wie lade ich die Prometheus-Konfiguration neu, ohne den Container neu zu starten?

Sende einen HTTP-POST an den Lifecycle-Endpunkt (erfordert das Flag --web.enable-lifecycle, das in dieser Anleitung bereits enthalten ist):

curl -X POST http://localhost:9090/-/reload

Alternativ geht auch ein SIGHUP-Signal an den Container: docker kill --signal=SIGHUP prometheus. Ein vollständiger Neustart ist damit nicht notwendig.

Wie füge ich einen neuen Scrape-Target hinzu?

Trage unter scrape_configs in der prometheus.yml einen neuen Job ein:

  - job_name: "mein-dienst"
    static_configs:
      - targets: ["mein-dienst-container:8080"]

Anschließend Konfiguration neu laden (siehe oben). Kein Neustart notwendig. Prometheus sucht alle 15 Sekunden nach neuen Metriken auf dem angegebenen /metrics-Endpunkt.

Wie lange werden Metriken gespeichert und wie viel Speicherplatz wird benötigt?

Standard: 15 Tage, einstellbar über PROMETHEUS_RETENTION in der .env-Datei (z. B. 30d oder 90d). Als Faustregel gilt: 1–2 Bytes pro Sample. Bei 10.000 aktiven Zeitreihen und 15 Sekunden Scrape-Intervall werden etwa 1–2 GB pro Woche verbraucht. Zusätzlich empfiehlt sich das Flag --storage.tsdb.retention.size als Obergrenze, um unkontrolliertes Disk-Wachstum zu verhindern.

Kann Prometheus auch Push-Metriken empfangen?

Prometheus ist primär für das Pull-Modell ausgelegt. Für kurzlebige Batch-Jobs und einmalige Prozesse gibt es den Pushgateway (prom/pushgateway, Port 9091) als Zwischenspeicher. Ab Prometheus v2.31+ unterstützt Prometheus zudem einen Remote Write Receiver per --web.enable-remote-write-receiver-Flag für direktes Push-Protokoll.

Wie betreibe ich Prometheus hinter einem Reverse Proxy?

Prometheus unterstützt URL-Präfixe per --web.external-url (z. B. http://monitoring.example.com/prometheus) und --web.route-prefix für den internen Pfad. Der Reverse Proxy muss den Pfad korrekt weiterleiten. Wie du Traefik als Docker-Reverse-Proxy mit automatischem HTTPS konfigurierst, zeigt Traefik als Docker-Reverse-Proxy mit automatischem HTTPS.

Warum keinen „latest"-Tag verwenden?

prom/prometheus:latest kann ohne Vorwarnung auf eine neue Hauptversion zeigen – also z. B. von v2.x auf v3.x mit Breaking Changes in PromQL oder der TSDB. Explizite Tags wie v3.12.0 geben dir Kontrolle darüber, wann du updatest, und ermöglichen ein einfaches Rollback.

Fazit

Mit diesem Docker-Compose-Stack hast du ein vollständiges Monitoring-Fundament aufgebaut: Prometheus v3.12.0 sammelt Metriken nach dem Pull-Prinzip, Node Exporter liefert über 1.000 Host-Metriken, Grafana macht die Daten mit mächtigen Dashboards sichtbar, und Alertmanager wartet bereits auf seine ersten Alert-Regeln. Die Kombination aus benannten Volumes, expliziten Image-Tags, WAL-Komprimierung und dem --web.enable-lifecycle-Flag sorgt für einen wartungsarmen, produktionstauglichen Betrieb. Der nächste sinnvolle Schritt ist die Konfiguration echter Alert-Regeln und das Anbinden weiterer Exporters für Datenbanken, Container oder Anwendungen – der Stack ist dafür von Anfang an vorbereitet.

Weiterführende Anleitungen und Quellen

  1. Prometheus Alerts an Telegram und Discord senden: Alertmanager konfigurieren
  2. cAdvisor mit Prometheus: Docker-Container-Metriken sammeln und in Grafana visualisieren
  3. Grafana-Dashboards bauen – von der Datenquelle zum Panel
  4. Beszel Server Monitoring mit Docker einrichten
  5. Docker und Docker Compose auf Linux installieren (Ubuntu/Debian)
  6. Traefik als Docker-Reverse-Proxy mit automatischem HTTPS
  7. 3-2-1-Backup-Strategie umsetzen

Offizielle Quellen: Prometheus Installationsdokumentation, Prometheus GitHub Repository, prom/prometheus auf Docker Hub, Prometheus Storage-Dokumentation.