Stand up a self-hosted health-check service (Gatus), tailnet-reachable #232
Labels
No labels
burndown-2026-06
burndown-2026-08
autonomy
async-consult
autonomy
epic
autonomy
headless
autonomy
live-collab
coherence-core
priority
P0
priority
P1
priority
P2
priority
P3
priority
P4
qa-fixture
role/advocate
role/director
role/exec
role/frontend
role/gamedev
role/human
role/platform
role/qa
role/science
role/sysadmin
state
ambient
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
coilyco-flight-deck/infrastructure#232
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What's missing
There is no continuous health-check / uptime monitor for the production floor today. When forgejo, gauntlet, eco-jobs-tracker, or one of the eco-side services goes down, the first signal is Kai noticing manually or a downstream agent erroring out. No paging, no historical uptime record, no SLO surface.
The k3s cluster on kai-server has liveness/readiness probes inside each workload, but those are local to the pod. They do not answer "is the public endpoint actually reachable from outside the cluster?" and they do not answer "is the tailnet-only endpoint reachable from a probe living inside the tailnet?".
Why now
Desired shape
A self-hosted health-check service running inside the k3s cluster, deployed via the existing Ansible + k3s path (same shape as the other services in
infrastructure/). Config-as-code over a UI-driven tool, so check definitions live in this repo and follow the same review path as everything else.Probes need to cover:
*.coilysiren.mesurface.100.x.x.xor*.ts.netthat should never be public. Because the probe runs on kai-server which is already a tailnet node, this is reachable for free, no sidecar gymnastics required.Alerting routes through whatever notification surface fits cleanly with the existing stack (Discord webhook is the lowest-friction first hop given
coily ops discordis already wired; Slack / email can come later).Candidate stacks
Ranked by fit with the IaC / config-as-code posture:
The recommendation is Gatus as the primary, with Healthchecks.io added later when there is a real cron job that needs dead-man coverage.
Tailscale reach: the easy path
Because kai-server is already a tailnet node, a Pod scheduled on it inherits no tailnet reach by default (k3s networks the pod, not the host). Two clean options:
hostNetwork: trueso it shares kai-server's network namespace and sees the tailnet directly. Simplest, no sidecar.Option 1 is the right shape for a single-node cluster running one health-check pod. Revisit option 2 only if a second workload ever needs the same trick.
Open questions
Done definition
infrastructure/.production_floor.mdcovered, plus forgejo and o2r.Filed by Codex during a routing handoff from Kai's Kapwing workspace.
Backlog burndown 2026-06-17: closing low-priority (P3/P4) to bring the open count to a manageable level. Nothing lost — reopen if this resurfaces. Batch tag:
burndown-2026-06.