Selbst gehosteter, S3-kompatibler Objektspeicher für Backups: MinIO hinter einem Nginx-Proxy, dazu ein rclone-basierter Backup-Agent mit versionierten Buckets. Ihre Offsite-Backups ohne Cloud-Rechnung
Selbst gehosteter, S3-kompatibler Objektspeicher für Backups: MinIO hinter einem Nginx-Proxy, dazu ein rclone-basierter Backup-Agent mit versionierten Buckets. Ihre Offsite-Backups ohne Cloud-Rechnung
Metriken, Logs und Dashboards in einer Compose-Datei: Prometheus scrapt node-exporter und cAdvisor, Loki mit Alloy aggregiert Logs, ein vorkonfiguriertes Grafana visualizeiert. Der Stack, mit dem ich hier alles andere überwache.
Ein Deployment-Guide mit lauffähigen Beispielen — kein herunterladbares Produkt. Alles unten ist die tatsächlich eingesetzte Konfiguration, gekürzt auf das, worauf es ankommt.
services:
prometheus:
image: prom/prometheus:${PROMETHEUS_VERSION:-v2.55.0}
container_name: prometheus
restart: unless-stopped
networks:
- observability
volumes:
- ./config/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:-30d}
- --web.console.libraries=/etc/prometheus/console_libraries
- --web.console.templates=/etc/prometheus/consoles
- --web.enable-lifecycle
logging:
driver: json-file
options:
max-size: 10m
max-file: "3"
labels:
- observability.service=prometheus
grafana:
image: grafana/grafana:${GRAFANA_VERSION:-11.4.0}
container_name: grafana
restart: unless-stopped
networks:
- observability
volumes:
- grafana_data:/var/lib/grafana
- ./config/grafana/datasources:/etc/grafana/provisioning/datasources:ro
- ./config/grafana/dashboards:/etc/grafana/provisioning/dashboards:ro
- ./config/grafana/dashboards-definitions:/var/lib/grafana/dashboards:ro
environment:
- GF_SECURITY_ADMIN_USER=${GRAFANA_ADMIN_USER:-admin}
- GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_ADMIN_PASSWORD:-admin}
- GF_INSTALL_PLUGINS=${GRAFANA_PLUGINS:-grafana-piechart-panel}
- GF_SERVER_ROOT_URL=${GRAFANA_ROOT_URL:-http://localhost:3000}
- GF_AUTH_ANONYMOUS_ENABLED=${GRAFANA_ANON_AUTH:-false}
logging:
driver: json-file
options:
max-size: 10m
max-file: "3"
labels:
- observability.service=grafana
Auszug — prometheus, grafana aus der Compose-Datei. Die übrigen Services (proxies, init jobs, exporters) folgen demselben Muster und binden ihre Konfiguration aus einem config/-Verzeichnis ein.
Kopieren Sie .env.example zu .env und setzen Sie mindestens:
NETWORK_NAME=observability
PROMETHEUS_VERSION=v2.55.0
PROMETHEUS_RETENTION=30d
NODE_EXPORTER_VERSION=v1.8.2
CADVISOR_VERSION=latest
LOKI_VERSION=3.2.0
.env setzen — niemals die Beispielwerte übernehmenDen Stack lohnt er, wenn etwas bricht — und die Lesereihefolge entscheidet: Ein Alarm feuert auf einer Metrik, das Grafana-Panel zeigt, wann sich der Wert bewegt hat und was sich daneben veränderte, und Loki beantwortet das warum — in die Log-Sicht wechseln, denselben Zeitraum und dasselbe Label-Set halten (Host, Container, Service), dann stehen die Fehlerzeilen genau an der Stelle, an der die Metrik kippte. Fixen, dann die Erholung auf demselben Panel bestätigen, statt den Sieg aus dem Gedächtnis zu erklären. Diese Schleife — Metrik, Panel, Logs, Fix, Panel — ist der tägliche Fahrer; alles andere im Stack existiert, um sie schnell zu machen.
Dashboards sind für Menschen, die bereits hinschauen; Alarme sind für alle
anderen. Bevor schöne Panels entstehen, die langweiligen Fünf definieren:
Host down (node-exporter up == 0), Platte läuft voll
(node_filesystem_avail_bytes über 85 Prozent), ein Scrape-Target down
(up == 0 pro Service), Zertifikat läuft in unter 14 Tagen ab, und ein
Container im Restart-Loop (Restart-Count über 15 Minuten steigend). Jeder
davon mappt auf eine konkrete Handlung um 3 Uhr nachts — das ist der echte
Test für einen Alarm. Hübsche Dashboards warten, bis der Pager ruhig ist.
Zwei stille Killer wohnen in jedem Metriken-Stack. Label-Kardinalität:
Ein Label mit unbegrenzten Werten — User-IDs, Request-Pfade, Container-IDs —
vervielfacht Zeitreihen, bis Prometheus RAM frisst und Queries kriechen.
Labels auf begrenzte Mengen beschränken (Host, Service, Schweregrad) und
Details nach Loki legen, wo sie hingehören. Retention-Defaults: Die
30-Tage-Standard-Retention von Prometheus reicht für den Betrieb, aber
irgendwann fragt jemand nach "den Zahlen vom letzten Jahr" — jetzt
entscheiden, ob das remote_write in einen Objektspeicher ist oder ein höfliches
Nein. Bei Loki die Retention explizit in config/loki.yml setzen; unbegrenzte
Log-Aufbewahrung ist der stillste Plattenfüller in diesem Stack.
Warum Prometheus und Loki statt einem Tool für beides? Metriken und Logs haben unterschiedliche Formen: Metriken sind voraggregierte Zahlen, die man günstig abfragt und alarmiert; Logs sind rohe Ereignisse, die man greppt, wenn etwas kaputt ist. Prometheus speichert die Zahlen, Loki die Ereignisse, und Grafana korreliert beide über Zeit und Labels. Ein Tool für beides wird in beidem mittelmäßig.
Wie viel Speicherplatz braucht der Stack?
Mit den Defaults — 30 Tage Prometheus-Retention und json-file-Log-Limits von
10 MB mal drei pro Container — läuft ein kleiner Single-Node-Host bequem mit
wenigen Gigabyte. Retention nur zusammen mit Speicherplanung erhöhen oder
Langzeit-Aufbewahrung an remote_write auslagern.
Warum sind Grafana-Datasources und Dashboards vorkonfiguriert? Alles in den Provisioning-Verzeichnissen wird beim Containerstart deklarativ angewandt. Ein neu gebauter Grafana kommt also mit Datasources und Dashboards zurück — kein Klick-Basteln, und die Konfiguration liegt im Git neben der Compose-Datei.
Wie binde ich eigene Anwendungen ans Monitoring an?
Metriken unter /metrics exportieren und einen Scrape-Target in
config/prometheus.yml ergänzen, oder Alloy auf dem App-Host laufen lassen,
der strukturierte Logs nach Loki weiterreicht. Dienste, die bereits
Prometheus-Metriken ausliefern — node-exporter, cAdvisor, die meisten
Infrastruktur-Images — brauchen nur einen Scrape-Eintrag.
Ein Guide, kein Produkt. Diese Seite ist Deployment-Dokumentation mit lauffähigen Beispielen — kein Zip, kein Download, kein Supportvertrag. Sie adaptieren die Muster auf Ihre eigene Umgebung, und das Ergebnis gehört Ihnen.
Wenn Sie das produktionsreif in Ihrer Infrastruktur wollen: Ich richte das für Teams im eintägigen Workshop Observability ein — Details auf der Consulting-Seite.