# Quadlet unit: alertmanager (rootless, boot-persistent). # # Install path on dankclaw: ~/.config/containers/systemd/alertmanager.container # Unit name: alertmanager.service (container name: alertmanager) # # The delivery half of the LLM alert rules. Until 2026-09-17 the rules in # shared/prometheus/rules/llm-fleet.yml evaluated and reached nobody — a # firing alert was visible in Prometheus and on the Grafana dashboard and # nowhere else, and an undelivered alert looks identical to a quiet one. # This unit closes that gap: Prometheus pushes to alertmanager:9093 over the # dankclaw_default network, and the single receiver webhooks the host-side # signal-relay user unit, which hands the text to signal-cli under Frank's # existing Signal account. # # PUBLISHING. 127.0.0.1 only, like every other observability unit: the # unauthenticated Alertmanager API (lifecycle endpoints are always on in # this binary — there is no flag to gate them) has no business on a host # interface, and no off-host consumer needs it. Caddy gains no vhost for # it; the homepage timer probes loopback. # # CONFIG. /opt/alertmanager/config/alertmanager.yml is installed from # shared/prometheus/alertmanager.yml by deploy-remote.sh on every deploy, so # the repo copy is the source of truth. STATE lives in /opt/alertmanager/data. # # Rootless: container root maps to the invoking user (dank) in this user # namespace and dank owns /opt/alertmanager/data. The image's default user # (nobody) maps to a subuid that cannot write it — same User=0:0 as prometheus. [Unit] Description=Alertmanager alert delivery (Dankclaw) After=network-online.target Wants=network-online.target [Container] ContainerName=alertmanager Image=docker.io/prom/alertmanager:latest Network=dankclaw_default User=0:0 Exec=--config.file=/etc/alertmanager/alertmanager.yml --storage.path=/alertmanager PublishPort=127.0.0.1:9093:9093 Volume=/opt/alertmanager/config:/etc/alertmanager Volume=/opt/alertmanager/data:/alertmanager HealthCmd=wget --spider -q http://localhost:9093/-/healthy HealthInterval=30s HealthTimeout=10s HealthRetries=3 HealthStartPeriod=30s [Service] Restart=always RestartSec=10 [Install] WantedBy=default.target