global: scrape_interval: 15s rule_files: - /etc/prometheus/alerts.yml # Join Container-UUID -> Klarname, einmal vorweggenommen (#0002). - /etc/prometheus/gameserver-rules.yml alerting: alertmanagers: - static_configs: - targets: ["alertmanager:9093"] # Zusaetzlich zu diesen Scrape-Targets kommen Metriken per Remote-Write rein # (k3s-Cluster: flux, kube_state_metrics; Matrix-Server: synapse). scrape_configs: ## Operating-Server (dieser Host) - job_name: "operating_prometheus" static_configs: - targets: ["localhost:9090"] - job_name: "operating_node-exporter" static_configs: - targets: ["node-exporter:9100"] - job_name: "operating_cadvisor" # cadvisor laeuft im Portainer-Stack "thread-net-git", selbes traefik-Netz static_configs: - targets: ["cadvisor:8080"] # Alertmanager-Eigenmetriken. Ohne diesen Job sind ZUSTELLfehler unsichtbar: # Prometheus kennt alertmanager zwar als Alarm-Ziel (oben unter alerting:), # scrapt ihn aber nicht - eine still reissende Alarmkette waere also genau das, # was niemand meldet. Liefert u.a. alertmanager_notifications_failed_total. - job_name: "operating_alertmanager" static_configs: - targets: ["alertmanager:9093"] - job_name: "operating_traefik" metrics_path: "/metrics" static_configs: - targets: ["traefik:8080"] ## Externe Hosts - job_name: "k3s_host_node" static_configs: - targets: ["10.0.0.2:9100"] labels: instance: "k3s-host" # ========================================================================== # Game-Host, privat ueber den vSwitch (management #0002). # # Bis 2026-08-20 zeigten die Targets auf 157.90.155.206 und waren seit dem # ersten Scrape nie up. Ursache war nicht die Firewall, sondern: Die # Exporter-Container veroeffentlichten ihre Ports gar nicht. # # Host-Seite deployt und verifiziert am 2026-08-20 (Uebergabe des Game-Host- # Betreibers). Ports auf 10.0.0.4, NICHT auf 0.0.0.0 - letzteres umginge ufw. # cadvisor liegt host-seitig auf 8081, weil coolify-proxy 0.0.0.0:8080 haelt. # # metric_relabel_configs gehoeren immer dem SCRAPENDEN Prometheus. Der # Game-Host hatte sein Label-Konzept lokal; mit dem Rueckbau seines eigenen # Prometheus wandert es hierher, sonst faellt es ersatzlos weg. # # instance = "gameserver" statt "pterodactyl": Damit tragen Metrik und Log # denselben Schluessel - promtail setzt host="gameserver". Kostet keine # Historie, die Targets sind am 2026-08-20 zum ersten Mal ueberhaupt up # gegangen. # ========================================================================== - job_name: "pterodactyl_host_node" static_configs: - targets: ["10.0.0.4:9100"] labels: host: gameserver relabel_configs: - target_label: instance replacement: gameserver metric_relabel_configs: # node-exporter meldet als nodename die UTS-Kennung SEINES Containers. # Betrifft nur node_uname_info und repariert $nodename in "Node Exporter # Full". Der Host setzt zusaetzlich hostname: gameserver - beides zusammen # ist widerspruchsfrei. - source_labels: [nodename] regex: '.+' target_label: nodename replacement: gameserver - job_name: "gameserver_cadvisor" static_configs: - targets: ["10.0.0.4:8081"] labels: host: gameserver relabel_configs: - target_label: instance replacement: gameserver metric_relabel_configs: # 1) Gameserver-Container heissen nur nach ihrer UUID. In ein eigenes # Label kopieren, damit der Join auf pterodactyl_server_info moeglich # wird - siehe gameserver-rules.yml. - source_labels: [name] regex: '([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})' target_label: uuid replacement: '$1' # 2) "display" = der Name, den Menschen lesen sollen. Zwei Stufen: roher # Container-Name, dann ohne die 24-stellige Coolify-Kennung. # "homepage-pqr9de7xmm8s5cpm2yss69s3" -> "homepage" - source_labels: [name] regex: '(.+)' target_label: display replacement: '$1' - source_labels: [name] regex: '(.+)-[a-z0-9]{24}' target_label: display replacement: '$1' # 3) Wings setzt an Gameserver-Containern gar keine Docker-Labels - ohne # diese zwei Regeln blieben sie als einzige ohne app/stack. - source_labels: [name] regex: '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}' target_label: app replacement: 'gameserver' - source_labels: [name] regex: '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}' target_label: stack replacement: 'pterodactyl' # 4) Sprechende Kurzlabels. Die Coolify-Regel steht jeweils HINTER der # Compose-Regel und ueberschreibt sie: com.docker.compose.project # liefert die Kennung, coolify.resourceName den sprechenden Namen. - source_labels: [container_label_com_docker_compose_service] regex: '(.+)' target_label: app replacement: '$1' - source_labels: [container_label_coolify_serviceName] regex: '(.+)' target_label: app replacement: '$1' - source_labels: [container_label_com_docker_compose_project] regex: '(.+)' target_label: stack replacement: '$1' - source_labels: [container_label_coolify_resourceName] regex: '(.+)' target_label: stack replacement: '$1' # 5) Rund 20 container_label_* je Serie (Image-Hashes, Traefik-Router, # Pfade) fliegen raus. - regex: 'container_label_.*' action: labeldrop # 6) container_*-Serien ohne name sind systemd-cgroup-Slices, die # node-exporter ohnehin abdeckt. machine_*-Metriken bleiben erhalten, # deshalb muss __name__ hier mitgreifen. - source_labels: [__name__, name] regex: 'container_.+;' action: drop # Port 9810, NICHT 9531: Der bisherige Exporter (loens2) auf 9531 hat nie # funktioniert - er rief die Client-API mit einem Application-Key auf und ueber # http statt https und lieferte deshalb null pterodactyl_*-Metriken. Ersetzt # durch einen Exporter, der die Panel-MariaDB read-only liest und gar keinen # API-Key braucht. - job_name: "pterodactyl_exporter" static_configs: - targets: ["10.0.0.4:9810"] labels: host: gameserver relabel_configs: - target_label: instance replacement: gameserver # CVE-Exporter (gitops#47) - job_name: "cve_exporter" static_configs: - targets: ["cve-exporter:9101"]