Alertmanager was configured as an alerting target but never scraped, so its own
metrics were absent: a silently breaking alert chain could not report itself —
the same blind spot as a missing series, now at the end of the chain. Adds the
operating_alertmanager scrape job and AlertDeliveryFailing on
alertmanager_notifications_failed_total.
The README still claimed alert delivery was deliberately muted via a
room=security null receiver. That route is gone; alertmanager.yml routes
everything to the matrix receiver, so the backup alerts added yesterday do get
delivered. Documentation asserting the opposite is dangerous in both directions,
so it now states the current wiring and keeps the alert-storm history as
background.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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 <noreply@anthropic.com>
Die CVE-Pipeline aus #47 ist deployt und sammelt Daten, die Alarm-Zustellung
ist aber bewusst abgeklemmt: room="security" routet auf einen Null-Receiver.
Grund: die Regeln erzeugen eine Alarm-Instanz pro CVE pro Image (bei 14 von 29
gescannten Images bereits 59 CRITICAL / 445 HIGH). group_by legt alle in eine
Gruppe, matrix-alerts.py schickt eine Nachricht pro Alarm -> Schwall. Dazu
steht save_state() hinter der Sende-Schleife: bricht ein Send ab (Synapse
rate-limitet nach ~10 mit 429), wird kein State gespeichert, der Receiver
antwortet 502 und Alertmanager wiederholt die ganze Gruppe -- mit leerer
Deduplizierung. Details und Weg zum Scharfschalten im README.
Ausserdem dokumentiert: Config-Aenderungen an prometheus.yml/alerts.yml/
alertmanager.yml werden von "docker compose up -d" NICHT aktiv. Die Dateien
sind einzeln gemountet, Docker haengt den Mount am Inode, git pull erzeugt
beim Umbenennen einen neuen -- der Container sieht weiter die alte Datei.
Es braucht --force-recreate; ein SIGHUP laedt nur den alten Inhalt erneut.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- Grafana-Provisioning ergaenzt: Datasources (prometheus/loki) mit den
bestehenden UIDs, damit alle Dashboards weiter funktionieren, sowie vier
Dashboard-Provider passend zu den vorhandenen Ordnern.
- 9 Dashboards aus der laufenden Instanz exportiert und bereinigt: id/version
entfernt, hart kodierte und verwaiste Datasource-UIDs auf die
provisionierten UIDs umgeschrieben.
- Images von :latest auf feste Versionen gepinnt (Prometheus v3.3.1,
Loki 3.7.1, Alloy v1.16.0, Grafana 12.0.0, node-exporter v1.9.1).
- Alloy: Docker-Metadaten (container, compose_service, compose_project) als
Loki-Labels via discovery.relabel.
- .env-Variablen auf GRAFANA_ADMIN_USER/GRAFANA_ADMIN_PASSWORD vereinheitlicht,
.env.example ergaenzt, .env bleibt ungetrackt.
- prometheus.yml kommentiert (Remote-Write-Quellen, Fremd-Stack-Targets),
toten auskommentierten Matrix-Job entfernt.
- README mit Deployment, Struktur, externen Abhaengigkeiten und offenen
Sicherheitspunkten (offene Ports 9090/3100/9100).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>