Retiring dankclaw/compose.yaml and adding alert rules invalidated claims across
the repo, including in the rule file agents read first. Clean cutover includes
the prose.
**Tests that had gone hollow.** Four assertions grepped dankclaw/compose.yaml
for a service name. With the file gone they passed by *absence* — a gate that
can no longer fail. Each now asserts the real invariant ("no dankclaw compose
file competes with the quadlet units") and keeps a live check for a re-added
entry, so it still fails when one appears: verified by recreating a compose file
with a comfyui service and watching three tests go red, then removing it.
**AGENTS.md, which was wrong about ComfyUI.** It said ComfyUI runs CPU-only
("no ROCm wheels for gfx1151, CUDA images wrong"). That was true in the
compose era and is false now: the restored unit runs with /dev/kfd + /dev/dri and
must NOT pass --cpu. An agent trusting the rule file would have re-broken it.
Also corrected: the observability paragraph ("RUNNING BUT UNCONFIGURED, no
datasource, no rules" — all three have been configured since 2026-09-16), the
Active runbook row that still named halogen for frank-large, halogen's absence
from the Retired table, the benchmark policy naming halogen's harness, and the
seam list.
**Unit and page claims.** prometheus.container said "no alerting rules anywhere
in this stack"; node-exporter.container said Dankserver runs from its compose
stack; Prometheus.md documented three jobs as working (they scrape HTML: they
can never report up) and said no dashboard existed; index.md and the three
authentik service pages pointed at the retired file; Authentik.md's upgrade
instruction told you to bump an image tag in it.
One bad edit of my own on the way (a stale line number clobbered a See Also
entry in Prometheus.md) — caught by reading back, fixed, and the vault link
checker now proves the cross-references hold.
64 lines
2.7 KiB
INI
64 lines
2.7 KiB
INI
# Quadlet unit: prometheus (rootless, boot-persistent).
|
|
#
|
|
# Install path on dankclaw: ~/.config/containers/systemd/prometheus.container
|
|
# Unit name: prometheus.service (container name: prometheus)
|
|
#
|
|
# The homelab metrics store. This replaces the compose service of the same
|
|
# name in dankclaw/compose.yaml ("Observability" block): these five containers
|
|
# were started by hand with podman-compose and never came back after a reboot,
|
|
# which the 2026-09-11 reboot for the amd_iommu=off change made obvious.
|
|
#
|
|
# PUBLISHING. The published port is bound to 127.0.0.1 deliberately. Prometheus
|
|
# is reached by Caddy over the dankclaw_default network (the Caddyfile's
|
|
# post-auth handler proxies to prometheus:9090) and by the host-side homepage
|
|
# status timer over 127.0.0.1. The compose service published on 0.0.0.0, which
|
|
# put an UNAUTHENTICATED metrics API — with the lifecycle endpoint enabled —
|
|
# on every host interface: a bypass around the Anubis + Authentik guard on
|
|
# prometheus.franksdank.cloud. No off-host consumer needs it.
|
|
#
|
|
# CONFIG. /opt/prometheus/config/prometheus.yml is installed from
|
|
# shared/prometheus/prometheus.yml by deploy-remote.sh on every deploy, so the
|
|
# repo copy is the source of truth. STATE (30-day retention) lives in
|
|
# /opt/prometheus/data.
|
|
#
|
|
# Rootless: container root maps to the invoking user (dank) in this user
|
|
# namespace and dank owns /opt/prometheus/data. The image's default user
|
|
# (nobody) maps to a subuid that cannot write it.
|
|
#
|
|
# RULES. Five LLM alert rules and one recording rule load from
|
|
# /etc/prometheus/rules/ (installed from shared/prometheus/rules/ by the
|
|
# deployer). There is still **no Alertmanager**, so nothing is delivered: a
|
|
# firing alert is visible in Prometheus and on the Grafana dashboard's ALERTS
|
|
# panel and reaches nobody. Delivery is an operator decision, not an oversight;
|
|
# the fragility is that an undelivered alert looks identical to a quiet one.
|
|
#
|
|
# The config volume is also why rules belong in git: editing them in the UI is
|
|
# lost on the next deploy, since the deployer overwrites the whole directory.
|
|
|
|
[Unit]
|
|
Description=Prometheus metrics store (Dankclaw)
|
|
After=network-online.target
|
|
Wants=network-online.target
|
|
|
|
[Container]
|
|
ContainerName=prometheus
|
|
Image=docker.io/prom/prometheus:latest
|
|
Network=dankclaw_default
|
|
User=0:0
|
|
Exec=--config.file=/etc/prometheus/prometheus.yml --storage.tsdb.path=/prometheus --storage.tsdb.retention.time=30d --web.enable-lifecycle
|
|
PublishPort=127.0.0.1:9090:9090
|
|
Volume=/opt/prometheus/config:/etc/prometheus
|
|
Volume=/opt/prometheus/data:/prometheus
|
|
HealthCmd=wget --spider -q http://localhost:9090/-/healthy
|
|
HealthInterval=30s
|
|
HealthTimeout=10s
|
|
HealthRetries=3
|
|
HealthStartPeriod=30s
|
|
|
|
[Service]
|
|
Restart=always
|
|
RestartSec=10
|
|
|
|
[Install]
|
|
WantedBy=default.target
|