Skip to content

mutana-heartbeat

Metadata

Field Value
Service mutana-heartbeat
Purpose Publish a privacy-reduced Uptime Kuma status snapshot to mutana.xyz
Criticality Tier 2
Owner Platform owner
Clusters homelab
Namespace monitoring (shared, pre-existing)
Exposure none; outbound HTTPS/FTP only
Stateful no
Backup class none; output is derived
RPO / RTO 15-minute cadence / next successful run
Last reviewed 2026-08-28

1. Service Overview

mutana-heartbeat is a scheduled, stdlib-only Python publisher. It reads the explicitly curated public Uptime Kuma status page, optionally verifies https://mutana.xyz, reduces those inputs to display-safe fields, and atomically replaces status.json in WordPress uploads.

If it stops, Mutana keeps serving the last good file and marks it frozen after 45 minutes, then lost after six hours. The publisher does not affect the availability of Uptime Kuma or WordPress.

Dependencies

Dependency Type Why it matters
Uptime Kuma service in monitoring Public status-page metadata and heartbeat source
LWS FTP endpoint external Receives the generated status.json
mutana.xyz external Self-check and consumer of the status file
mutana-heartbeat-secret Kubernetes Secret Kuma and scoped FTP connection values

2. Architecture Diagram

[CronJob / 15 min, homelab:monitoring]
   -> GET public Kuma status-page metadata + heartbeat
   -> HEAD https://mutana.xyz
   -> reduce to display-only status.json
   -> STOR status.json.tmp
   -> RNFR/RNTO status.json (atomic)
        -> browser status page applies staleness rules

3. Deployment Specifications

Item Value
Source path mutana-heartbeat/
Deployment model Root Kustomization, manual first release
Namespace existing monitoring namespace
Workload kind CronJob
Image python:3.12-slim@sha256:09f7da3bc104798d0afb40bc08d23ab2da20a76130cec1f2ef170848f5d85217
Schedule */15 * * * *
Concurrency Forbid
Requests 100m CPU, 64Mi memory
RBAC none; ServiceAccount token automount disabled
Storage none
Config heartbeat.py generated into ConfigMap mutana-heartbeat-script

Cluster mapping

Cluster Entry point Notes
homelab mutana-heartbeat/kustomization.yaml Reuses the namespace and Kuma instance already used by the homelab monitoring stack

The root Kustomization is deliberate: the script ConfigMap is generated from the adjacent unit-tested source, avoiding an embedded duplicate. It is not in a Fleet GitRepo path yet.

4. Configuration Guide

Public data contract

The Kuma public status page is the monitor allowlist. Output contains generated_at, computed overall, and services with only name, category, state, uptime_24h, and uptime_7d. Public monitor names must not contain internal addresses, private hostnames, customer names, or sensitive topology.

Secrets management

Secret mutana-heartbeat-secret is created out of band in namespace monitoring. Required keys:

Key Purpose
KUMA_URL Reachable Kuma base URL
SLUG Public status-page slug
FTP_HOST TLS-valid publisher hostname
FTP_USER Scoped FTP account
FTP_PASS FTP password
FTP_DIR Existing WordPress uploads directory for that account

The committed secret.example.yaml contains placeholders only; local secret.yaml is gitignored. Rotate by updating the Secret and triggering a one-off Job. Without the Secret, Jobs fail and the previous public file remains intact.

5. Access Protocols

Path URL or endpoint Audience Auth TLS terminates at
Kuma status API Secret-defined internal/base URL publisher pod public status-page slug Kuma endpoint
Mutana self-check https://mutana.xyz publisher pod none LWS edge
WordPress uploads Secret-defined FTP host/directory publisher pod scoped FTP credentials FTP server when FTPS is available

There is no inbound Service or IngressRoute. The publisher attempts verified FTPS, warns and falls back to plain FTP only because the current hosting account may not expose FTPS on its configured endpoint.

6. Operations and Observability

  • Primary signals: CronJob last schedule/success time, failed Job count, Job exit code, and logs.
  • Public symptom: /statut/ reports frozen data after 45 minutes or a lost heartbeat after six hours.
  • Logs never print the password or Secret contents; they report fetch/upload failures and the published service count.
  • A one-off Job created from the CronJob is the standard post-change smoke test.

See the runbook for exact commands.

7. Backup and Recovery Notes

The workload is stateless and needs no PVC backup. Source and manifests live in Git; the Secret is recreated out of band. status.json is derived data and the prior successful version remains on LWS when a run fails.

Recovery requires a valid Secret, a public Kuma status page with reviewed display names, network access, and one successful Job. Do not restore or synthesize old status data as fresh.

8. Release and Change Notes

  • Initial release: stdlib publisher, deterministic offline fixture path, verified-FTPS-first atomic upload, hardened CronJob, and manual homelab Kustomize entry point.
  • Fleet activation is intentionally deferred until the operator reviews the production monitor allowlist and Secret.
  • Rollback: suspend/delete the CronJob or revert this workload. Mutana's staleness behavior is the user-visible fallback.