From 4cb9bfb2bcf6327d1ed7bf2844dada4a707320c5 Mon Sep 17 00:00:00 2001 From: sorb Date: Fri, 14 Aug 2026 12:00:00 +0000 Subject: [PATCH] fix(monitoring): mount prometheus/alertmanager config dirs, not single files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Deploying e0808ba surfaced the trap in practice: docker pins a single-file bind mount to the inode, git pull replaces files by rename, so the container kept serving the old alerts.yml while SIGHUP reported a successful reload — host and container md5 differed and BackupCronJobMissing simply was not there. The trap was already documented in this README, in detail, with the correct command and a verification snippet, and it still bit. A footgun you avoid only by reading gets stepped on eventually, so remove it structurally: directory mounts resolve through the path on every access. Config paths are unchanged, so --config.file keeps working. Remaining single-file mounts (loki, alloy, the scripts) are named in the README as still needing --force-recreate. Co-Authored-By: Claude Opus 4.8 --- monitoring/README.md | 46 +++++++++++++++++++++-------------- monitoring/docker-compose.yml | 13 +++++++--- 2 files changed, 38 insertions(+), 21 deletions(-) diff --git a/monitoring/README.md b/monitoring/README.md index a4ee1bd..585f234 100644 --- a/monitoring/README.md +++ b/monitoring/README.md @@ -13,34 +13,44 @@ docker network create traefik # falls noch nicht vorhanden docker compose up -d ``` -### ACHTUNG: Config-Aenderungen brauchen ein `--force-recreate` +### Config-Aenderungen: was wirklich ankommt -`docker compose up -d` allein aktiviert **keine** geaenderte Config-Datei. -Grund: `prometheus.yml`, `alerts.yml` und `alertmanager.yml` sind als -**einzelne Dateien** gemountet, und Docker haengt so einen Mount am Inode auf. -`git pull` schreibt eine neue Datei und benennt sie um -- neuer Inode. Der -Container zeigt danach weiter auf die alte Datei und sieht die Aenderung nie. -`up -d` merkt davon nichts (Service-Definition unveraendert -> kein Neustart), -und ein `SIGHUP`-Reload laedt bloss den alten Inhalt erneut. +**Prometheus und Alertmanager mounten seit 2026-08-15 ihr Config-VERZEICHNIS** +(`./prometheus`, `./alertmanager`) statt einzelner Dateien. Damit ist die frueher +hier beschriebene Inode-Falle fuer sie beseitigt: `git pull` ersetzt Dateien per +Rename (neuer Inode); ein Einzeldatei-Mount zeigt danach weiter auf die **alte** +Datei, waehrend `SIGHUP` seelenruhig Erfolg meldet. Verzeichnis-Mounts loesen bei +jedem Zugriff ueber den Pfad auf. -Nach jedem `git pull`, der eine dieser Dateien anfasst: +Warum strukturell statt per Anleitung: genau diese Falle war hier bereits +ausfuehrlich dokumentiert -- samt richtigem Kommando und Pruefbefehl -- und hat am +2026-08-14 trotzdem zugeschlagen (geladen wurden die alten Alert-Regeln, Reload +meldete Erfolg). Eine Fussangel, die man nur durch Lesen umgeht, umgeht man +irgendwann nicht. + +Nach einem `git pull`, der Configs anfasst: ```bash -docker compose up -d --force-recreate prometheus alertmanager +docker compose up -d # Mount-/Service-Aenderungen -> Container wird neu erstellt ``` -Ob es gewirkt hat, sieht man nur **im Container**, nicht auf der Platte: +Reicht bei Prometheus/Alertmanager fuer den Inhalt bereits ein Reload, ist das in +Ordnung -- die Datei ist jetzt wirklich die neue. + +**Noch als Einzeldatei gemountet** (gleiche Falle, dort weiterhin +`--force-recreate` noetig): `loki/loki-config.yaml`, `alloy/config.alloy` sowie die +Skripte `matrix-alerts.py`, `release-watch.py`, `cve-exporter.py`. + +Ob eine Aenderung angekommen ist, sieht man nur **im Container**, nie auf der Platte: ```bash -docker exec prometheus grep -c axion-cve /etc/prometheus/alerts.yml # 0 = alter Inode +docker exec prometheus md5sum /etc/prometheus/alerts.yml +md5sum prometheus/alerts.yml # muessen uebereinstimmen ``` -Nicht betroffen sind Verzeichnis-Mounts (`grafana/provisioning/`, -`grafana/dashboards/`) -- die loesen bei jedem Zugriff ueber den Pfad auf. -Grafana liest **Provider-Definitionen** allerdings nur beim Start: ein neuer -Ordner in `provisioning/dashboards/dashboards.yml` braucht einen -`docker compose restart grafana`. Neue oder geaenderte Dashboard-JSONs -innerhalb eines bestehenden Providers werden dagegen laufend nachgezogen. +Grafana liest **Provider-Definitionen** nur beim Start: ein neuer Ordner in +`provisioning/dashboards/dashboards.yml` braucht `docker compose restart grafana`. +Dashboard-JSONs innerhalb eines bestehenden Providers werden laufend nachgezogen. ## Struktur diff --git a/monitoring/docker-compose.yml b/monitoring/docker-compose.yml index a181464..9cccb38 100644 --- a/monitoring/docker-compose.yml +++ b/monitoring/docker-compose.yml @@ -4,8 +4,12 @@ services: container_name: prometheus restart: unless-stopped volumes: - - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro - - ./prometheus/alerts.yml:/etc/prometheus/alerts.yml:ro + # Verzeichnis- statt Einzeldatei-Mount: Docker haengt Einzeldatei-Mounts am + # Inode auf, und `git pull` ersetzt Dateien per Rename (neuer Inode) - der + # Container sah die Aenderung dann nie, waehrend SIGHUP brav Erfolg meldete. + # Verzeichnis-Mounts loesen bei jedem Zugriff ueber den Pfad auf. + # Config-Pfade bleiben unveraendert (--config.file zeigt weiter dorthin). + - ./prometheus:/etc/prometheus:ro - prometheus_data:/prometheus command: - '--config.file=/etc/prometheus/prometheus.yml' @@ -26,7 +30,10 @@ services: container_name: alertmanager restart: unless-stopped volumes: - - ./alertmanager/alertmanager.yml:/etc/alertmanager/alertmanager.yml:ro + # Verzeichnis-Mount, gleicher Grund wie bei Prometheus. Die beiden .py aus + # diesem Ordner liegen dadurch mit unter /etc/alertmanager - ungenutzt und + # harmlos, alertmanager laedt ausschliesslich --config.file. + - ./alertmanager:/etc/alertmanager:ro - alertmanager_data:/alertmanager command: - '--config.file=/etc/alertmanager/alertmanager.yml'