Verdict: Gatus ⭐ 11.2k. The hard requirement — monitor config lives in git, reproducible from a clean VM — eliminates four of the five candidates before any other axis matters. Uptime Kuma stores everything in SQLite via a GUI and removed its JSON export in v2 (October 2025) [1]. Healthchecks (self-hosted), Statping-ng, and the Prometheus Blackbox + Alertmanager + Grafana stack all either require GUI-driven state or carry an impractical container count for a single-node homelab. Only Gatus ships with config.yaml as the sole source of truth, auto-reloads on change, and needs one container [2].
The 87k vs 11k star gap is not a health signal here. Applying CHAOSS Contributor Absence Factor and commit-cadence criteria to both projects, Gatus is actively maintained with regular releases [2]. Kuma’s star advantage reflects years of viral GUI-driven adoption among users who want the opposite of what this brief requires: zero config files. A project with 87k stars that stores its state in a UI-managed SQLite database scores worse on config-as-code completeness than a project with 11k stars that is purely YAML-driven — star count measures community size, not gitops suitability [3].
Config-as-code completeness is the decisive axis. The config-as-code research identifies two common failure modes: state managed outside git, and secrets committed inside git. Kuma fails the first test by design. Gatus passes both: monitors are declared in config.yaml (in git), credentials are injected as environment variables at runtime (never committed) [2]. The result is a monitoring domain at IaC Level 4: every change is a pull request, every state is version-controlled, rollback is git revert.
What you lose is concrete and manageable. Gatus has no Docker container liveness monitor — replace with an HTTP HEALTHCHECK endpoint on each service Dockerfile, or point at Traefik’s /ping. Alert providers drop from Kuma’s 90+ to Gatus’s 20+, but Discord, ntfy, Telegram, and email cover every realistic homelab notification path [4]. Uptime history does not transfer; enable SQLite storage (storage: type: sqlite) so Gatus accumulates its own history across restarts and does not reset on container rebuild [5].
Operational weight is low. Single container, ~40 MB RAM at 50 endpoints vs Kuma’s ~100 MB [6], no separate database process, no UI-driven toil. Backup story for Gatus: the config.yaml is already in git; the only ephemeral asset is the SQLite uptime history file — back that up with Restic or Kopia alongside the rest of your homelab volumes. The 3-2-1-1-0 rule requires one immutable copy — apply S3 Object Lock or a MinIO WORM policy to the bucket receiving your Restic snapshots.
Traefik security is an active concern, not a hypothetical. CVE-2026-44774 (June 5, 2026) allows a low-privileged tenant in shared Gateway API deployments to overwrite live Traefik configuration via the REST provider [7]. For a Docker Compose homelab the blast radius is smaller, but the principle stands: expose Gatus’s status page via a Traefik router with ForwardAuth or BasicAuth middleware; never expose Traefik’s own API port (8080 by default) outside the Docker internal network; patch to v2.11.46+, v3.6.17+, or v3.7.1+.
The sharpest open question: Statping-ng’s maintenance status was flagged as a prerequisite check before recommending it, but the sub-topics did not directly audit its commit log or issue responsiveness — if Statping-ng is in any existing stack, apply the bus-factor tooling (npx -y git-truck, scorecard --repo) before trusting it with production alert paths.