Mit Node Exporter Docker Compose stellst Du Linux-Metriken für Prometheus bereit, ohne den Exporter als Paket auf dem Host zu installieren. Entscheidend sind Host-Netzwerk, Host-PID-Namespace und ein schreibgeschütztes Root-Dateisystem-Mount: Nur so beobachtet der Container den Server statt sich selbst.

Stand: 16.10.2026

Auf einen Blick

  • Node Exporter liefert standardmäßig HTTP-Metriken auf Port 9100.
  • Für Host-Monitoring braucht der Container network_mode: host, pid: host und --path.rootfs=/host.
  • Prometheus ruft den Endpunkt /metrics
  • Die Metriken des Exporters beginnen typischerweise mit node_.
  • Zusätzliche Collectoren aktivierst Du einzeln und beobachtest dabei Laufzeit und Kardinalität.

1. Die Ausgangslage und das Ziel

Teil 1 – Was Du aufbaust

Dieser Leitfaden baut eine klare Kette auf: Der Linux-Host liefert Daten, Node Exporter stellt sie als Prometheus-Textformat bereit, und Prometheus fragt sie regelmäßig ab. Danach kannst Du die Werte in der Prometheus-Oberfläche prüfen oder sie an einen bestehenden Grafana-Stack weiterreichen. Für das Dashboarding passt der Artikel zu Grafana Alloy mit Docker Compose; Node Exporter ersetzt ihn nicht, sondern ergänzt die Host-Sicht.

Node Exporter ist laut offiziellem README ein Prometheus-Exporter für Hardware- und Betriebssystemmetriken von Unix-artigen Kerneln. Er lauscht standardmäßig auf HTTP-Port 9100. Er ist damit kein allgemeiner Container-Monitor und kein Ersatz für ein Backup. Für die Sicherung von Docker-Volumes bleibt ein Verfahren wie Restic für Docker-Backups nötig.

Architektur mit Linux-Host, Node Exporter, Prometheus und Grafana.
Der Exporter liest den Host; Prometheus sammelt die Metriken ein.

Warum der Container besondere Rechte braucht

Ein Container sieht normalerweise sein eigenes Dateisystem und seinen eigenen Prozessraum. Genau das wäre für Host-Monitoring falsch: Die gemeldete Plattenbelegung und Prozesssicht wären dann die des Containers. Das Projekt beschreibt deshalb ausdrücklich zusätzliche Flags für Container-Deployments. Der Bind-Mount von / nach /host und der identische Wert bei --path.rootfs bilden die Grundlage.

2. Voraussetzungen und Architektur

Teil 2 – Prüfe die Entscheidung vor dem Start

Die folgende Variante richtet sich an einen Linux-Host mit Docker Compose und einen Prometheus-Server, der den Port 9100 erreichen darf. Windows benötigt laut Projekt den separaten Windows Exporter. Für Kubernetes ist diese Compose-Installation ebenfalls nicht das passende Deployment; dort sind DaemonSet und Cluster-Architektur maßgeblich. Einen grundlegenden Überblick liefert Kubernetes-Monitoring mit Grafana und Prometheus.

BausteinAufgabeEntscheidung
Node Exporterliest Host-Metriken und bietet sie anläuft als einzelner Container je Linux-Host
Docker Host-Netzwerkstellt Port 9100 im Host-Netz bereitkein separates Container-Port-Mapping
Prometheusholt Metriken per Scrape abkennt ein Ziel pro überwachten Host
Grafanavisualisiert abgeholte Zeitreihenoptional und nach Prometheus angeschlossen

Plane den Zugriff bewusst: Der Endpoint zeigt Betriebsdaten. Daher sollte Port 9100 nicht unkontrolliert aus dem Internet erreichbar sein. Begrenze stattdessen auf das Monitoring-Netz oder den Prometheus-Host. Das ist ein Netzthema, nicht eine Eigenschaft, die Node Exporter automatisch für Dich löst. Die Basis für einen sauberen Reverse Proxy behandelt Traefik im Homelab mit Docker Compose; für diesen internen Metrik-Port ist ein Proxy jedoch meist nicht nötig.

3. Node Exporter Docker Compose anlegen

Teil 3 – Die Compose-Datei verstehen

Lege die Compose-Datei für den Host an, den Du beobachten willst. Die folgende Konfiguration entspricht dem Docker-Compose-Beispiel aus dem offiziellen Node-Exporter-README. Sie nutzt das Image aus Quay, verbindet den Prozess- und Netzwerk-Namespace mit dem Host und bindet dessen Root-Dateisystem nur lesbar ein.

---
version: '3.8'

services:
  node_exporter:
    image: quay.io/prometheus/node-exporter:latest
    container_name: node_exporter
    command:
      - '--path.rootfs=/host'
    network_mode: host
    pid: host
    restart: unless-stopped
    volumes:
      - '/:/host:ro,rslave'

Der Erfolg zeigt sich nach dem Start daran, dass der Dienst auf dem Host-Port 9100 antwortet. restart: unless-stopped sorgt laut Beispiel dafür, dass der Container nach einem Docker- oder Host-Neustart erneut gestartet werden kann, sofern er nicht bewusst gestoppt wurde.

Die kompakte Alternative ohne Compose nutzt dieselben drei Kernelemente. Sie ist hilfreich, um die Bedeutung der Optionen zu vergleichen, aber für einen dauerhaft dokumentierten Betrieb ist die Compose-Datei meist besser nachvollziehbar.

docker run -d \
  --net="host" \
  --pid="host" \
  -v "/:/host:ro,rslave" \
  quay.io/prometheus/node-exporter:latest \
  --path.rootfs=/host

Auch hier ist Erfolg nicht der bloße Container-Start, sondern die Auslieferung von Host-Metriken. Verwende nie beide Varianten gleichzeitig auf demselben Host, weil beide Port 9100 verwenden.

Host-Dateisystem und Mounts

Der Mount ist absichtlich schreibgeschützt. Außerdem weist die Projektdokumentation darauf hin, dass alle nicht unter Root eingehängten Mount-Punkte, die Du beobachten willst, in den Container eingebunden werden müssen. Prüfe daher besonders Datenplatten, NAS-Mounts und eigene Mount-Punkte. Ohne passenden Bind-Mount kann der Exporter sie nicht unter dem mit --path.rootfs definierten Wurzelpfad sehen.

Der Dateisystem-Collector liefert unter anderem Informationen zu genutztem Speicherplatz. Er ist standardmäßig aktiviert. Virtuelle und containerbezogene Mount-Punkte können die Übersicht jedoch unbrauchbar machen. Das Projekt dokumentiert dafür einen Exclude-Parameter:

--collector.filesystem.mount-points-exclude=^/(dev|proc|sys|var/lib/docker/.+|var/lib/kubelet/.+)($|/)

Wenn Du diesen Filter einsetzen willst, ergänze ihn als weiteren Eintrag unter command. Der Erfolg besteht darin, dass die unerwünschten Mount-Punkte nicht mehr in den Dateisystemmetriken auftauchen. Prüfe anschließend trotzdem, ob Deine produktiven Daten-Mounts weiter enthalten sind.

Ablauf vom Start der Compose-Datei bis zum erfolgreichen Prometheus-Scrape.
Verifikation folgt dem Datenweg: Endpoint zuerst, Scrape danach.

4. Prometheus an Node Exporter anbinden

Teil 4 – Den Scrape-Job gezielt konfigurieren

Der Exporter speichert keine Langzeitdaten. Deshalb braucht er Prometheus als Abnehmer. Die offizielle Prometheus-Anleitung verwendet einen Job namens node, ein Intervall von 15 Sekunden und localhost:9100. Verwende localhost nur, wenn Prometheus auf demselben Host und im selben Netzwerk-Kontext läuft. Andernfalls ersetzt Du ihn durch die erreichbare Host-Adresse.

global:
  scrape_interval: 15s

scrape_configs:
- job_name: node
  static_configs:
  - targets: ['localhost:9100']

Die Konfiguration gehört in die von Prometheus geladene Datei. Laut offiziellem Schritt-für-Schritt-Leitfaden startet Prometheus mit einer expliziten Konfigurationsdatei so:

./prometheus --config.file=./prometheus.yml

Der Erfolg ist ein erreichbarer Target-Eintrag im Prometheus-Status und ein Wert für up. Ein bloß geöffneter Port reicht nicht: Erst ein erfolgreicher Scrape beweist, dass Prometheus den richtigen Endpoint liest.

Targets passend wählen

Für mehrere Hosts ergänzt Du im selben Job mehrere Ziele oder strukturierst Jobs nach Umgebung. Wichtig ist, dass jede Zieladresse aus Sicht von Prometheus erreichbar ist. Vermeide es, Docker-Service-Namen und Host-Adressen zu vermischen: Mit network_mode: host ist der Endpoint am Host-Netz, nicht in einem Compose-Bridge-Netz veröffentlicht.

Die allgemeine Prometheus-Konfigurationsreferenz beschreibt scrape_configs als Liste der Scrape-Konfigurationen. Bleibe bei einer kleinen, expliziten Zielmenge, solange Du keine Service-Discovery einsetzt. Das macht Fehler bei Adresse, Firewall und DNS deutlich sichtbar.

5. Metriken sinnvoll lesen

Teil 5 – Erst Datenqualität, dann Dashboard

Der Metrik-Endpoint ist der direkteste Wahrheitstest. Die Prometheus-Anleitung nutzt folgenden Abruf:

curl http://localhost:9100/metrics

Erfolgreich ist ein Textformat mit Zeilen wie # HELP, # TYPE und Messwerten. Eine HTML-Seite oder ein Verbindungsfehler zeigt dagegen, dass Du nicht am erwarteten Exporter-Endpoint bist.

Um sich auf die Host-Metriken zu konzentrieren, verwendet die gleiche Anleitung einen Filter auf den Präfix node_:

curl http://localhost:9100/metrics | grep "node_"

Der Erfolg sind Einträge wie node_cpu_seconds_total oder node_exporter_build_info. Erst danach lohnt sich die Arbeit am Grafana-Dashboard. Ein grünes Docker-Icon ersetzt diese Prüfung nicht.

Viele Collector sind bereits aktiv, darunter CPU-, Speicher-, Dateisystem-, Netzwerk- und Disk-Statistiken. Zusätzliche Collector sind laut README bewusst standardmäßig deaktiviert: Gründe können hohe Kardinalität, längere Laufzeiten als das Scrape-Intervall oder hoher Ressourcenbedarf sein. Aktiviere sie daher einzeln, zuerst auf einem nicht produktiven System und danach auf nur einem produktiven Knoten.

./node_exporter -h

Die Hilfe zeigt die verfügbaren Flags des verwendeten Builds. Prüfe nach einer Collector-Erweiterung insbesondere scrape_duration_seconds, damit die Erfassung nicht ins Timeout läuft, sowie scrape_samples_post_metric_relabeling, damit die Zahl der Zeitreihen nachvollziehbar bleibt.

Die wichtigsten Stolperfallen

Der Exporter zeigt Container- statt Host-Werte

Symptom: Dateisystem- oder Prozesswerte wirken unplausibel klein. Ursache: Der Container sieht ohne Host-Mount und Rootfs-Pfad sein eigenes Dateisystem. Lösung: Setze --path.rootfs=/host und den Mount /:/host:ro,rslave mit identischem Pfad ein.

Port 9100 ist erreichbar, Prometheus zeigt das Target als fehlerhaft

Symptom: Ein lokaler Curl klappt, der Scrape aber nicht. Ursache: Die Zieladresse gilt aus Sicht von Prometheus, nicht aus Sicht Deiner Shell. Lösung: Prüfe die Adresse im targets-Eintrag und die Netzwerkfreigabe zwischen Prometheus und Host.

Nicht alle Datenplatten erscheinen

Symptom: Ein zusätzlicher Mount fehlt in den Dateisystemmetriken. Ursache: Nicht unter Root eingehängte Mount-Punkte wurden nicht in den Container gebunden. Lösung: Binde den betreffenden Mount zusätzlich ein und kontrolliere erneut den Endpoint.

Ein zusätzlicher Collector macht Scrapes langsam

Symptom: Scrapes laufen bis zum Timeout oder erzeugen sehr viele Serien. Ursache: Deaktivierte Collector können längere Laufzeiten, hohe Kardinalität oder Ressourcenbedarf haben. Lösung: Aktiviere jeweils nur einen Collector und beobachte scrape_duration_seconds sowie scrape_samples_post_metric_relabeling.

Der timex-Collector liefert nicht die erwarteten Werte

Symptom: Die zeitbezogenen Metriken fehlen bei einem System, auf dem Du sie erwartest. Ursache: Das README nennt für manche Systeme die zusätzliche Docker-Capability SYS_TIME. Lösung: Prüfe zuerst, ob Du den Collector überhaupt brauchst; ergänze nur dann gezielt --cap-add=SYS_TIME und dokumentiere die erweiterte Berechtigung.

Verifikation: So prüfst Du, dass alles läuft

Prüfe in dieser Reihenfolge, weil jede Stufe eine andere Fehlerklasse ausschließt. Zuerst muss der Exporter Text liefern, danach muss Prometheus genau dieses Ziel erfolgreich abholen.

curl http://localhost:9100/metrics | grep "node_"

Erwartet werden Zeilen mit dem Präfix node_, etwa node_cpu_seconds_total und node_exporter_build_info. Erscheint nichts oder ein Verbindungsfehler, prüfe die Compose-Konfiguration und den laufenden Container, bevor Du Prometheus änderst.

curl http://localhost:9100/metrics

Erwartet wird das Prometheus-Textformat: Hilfe- und Typ-Zeilen sowie Messwerte. Laut der Prometheus-Anleitung beginnt die Ausgabe beispielsweise mit Metadaten wie # HELP und # TYPE. Öffne anschließend die Prometheus-Oberfläche und kontrolliere den Status des Node-Jobs: Ein erfolgreicher Abruf macht dessen up-Zeitreihe verfügbar.

Fazit

Node Exporter Docker Compose funktioniert zuverlässig, wenn der Container bewusst Zugriff auf die Host-Namensräume und das Host-Dateisystem erhält. Die wichtigste Prüfung ist nicht der gestartete Container, sondern die Kombination aus lesbaren node_-Metriken und einem erfolgreichen Prometheus-Scrape. Filtere Mount-Punkte mit Bedacht und erweitere Collector nur schrittweise. So bleibt das Monitoring aussagekräftig, ohne unnötig viele Zeitreihen zu erzeugen.

Quellen

Häufige Fragen

Wie starte ich Node Exporter mit Docker Compose?

Lege eine Compose-Datei mit Host-Netzwerk, Host-PID-Namespace, dem schreibgeschützten Root-Mount und –path.rootfs=/host an. Starte sie anschließend mit Docker Compose und prüfe /metrics auf Port 9100.

Warum braucht Node Exporter im Container –path.rootfs?

Ohne diesen Pfad würde der Exporter das Dateisystem des Containers auswerten. Der Rootfs-Pfad verweist auf den eingebundenen Host-Wurzelpfad und ermöglicht Host-Metriken.

Welchen Port verwendet Node Exporter?

Node Exporter lauscht standardmäßig auf HTTP-Port 9100. Prometheus muss diesen Port vom jeweiligen Ziel aus erreichen können.

Wie prüfe ich Node Exporter Docker Compose?

Rufe curl http://localhost:9100/metrics auf. Eine erfolgreiche Installation liefert Prometheus-Textformat; beim Filter auf node_ erscheinen Host-Metriken wie node_cpu_seconds_total.

Warum fehlen Dateisystem-Metriken von einem Mount?

Nicht unter Root eingehängte Mount-Punkte müssen laut Projekt zusätzlich in den Container eingebunden werden. Prüfe danach erneut die Metriken und gegebenenfalls den Dateisystemfilter.