Files
ulicraft-server-v1/plan/10-uptime-kuma.md
Oier Bravo Urtasun d21a7f0e92 feat(landing): live server card backed by self-hosted mc-status
Add a featured live ServerCard to the landing (replaces the static
ServerListPanel in hero + status sections): server favicon, color MOTD,
online/offline pill, players online/max with fill bar, and a player-head
row rendered by our own NMSR from Drasl skins. Progressive enhancement —
SSG skeleton degrades gracefully when JS or the API is unavailable.

Back it with a self-hosted pinger instead of the public api.mcstatus.io:
mcstatus.io's API service is closed-source (only the mcutil library is
open), so docker/mc-status wraps mcutil and re-emits its v2 JSON shape,
keeping the frontend unchanged. The service ignores the path address and
only pings MC_STATUS_TARGET (no SSRF relay), with a 30s TTL cache.

Exposed same-origin via caddy at the apex /api/mcstatus/* path (no new DNS
subdomain or LE cert change, no CORS). Uptime Kuma stays the uptime
history + alerting backend; see plan/15-mc-status.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 22:08:30 +02:00

2.6 KiB

10 — Uptime Kuma

Distinct from plan/15-mc-status.md: Kuma is the uptime history + alerting backend; mc-status is the live data feed for the landing's server card. Both ping minecraft over mcnet but serve different purposes.

Status monitoring + public status page. Service uptime-kuma (louislam/uptime-kuma:1), web UI on :3001, reached only through caddy at https://status.${BASE_DOMAIN}. Joined to mcnet, so it can probe every other service by its internal container name.

Add a Minecraft monitor

Uptime Kuma 1.x ships a built-in Minecraft Server monitor type. It uses the Server List Ping protocol (the same ping the vanilla multiplayer list uses): unauthenticated, so it works fine with ONLINE_MODE=FALSE / ENFORCE_SECURE_PROFILE=FALSE. It reports latency, online/max players, and MOTD.

  1. Open https://status.${BASE_DOMAIN} and log in (admin account created on first run).
  2. + Add New Monitor.
  3. Monitor Type: Minecraft Server.
  4. Fill in one of the two probe targets below.
  5. Heartbeat Interval: 60 s (fine for a friends' server).
  6. Retries: 2, Retry Interval: 30 s — avoids flapping on a GC pause.
  7. Save.

Two targets — add both

Monitor Server Port What it proves
MC (internal) minecraft 25565 The server process is up and accepting pings inside mcnet.
MC (public) mc.${BASE_DOMAIN} 25565 The full path works: DNS → host firewall → docker port publish → server.

The public monitor is the one that catches "I can't connect" outages — firewall, DNS, or an unpublished port all show red here while the internal monitor stays green. Run both to tell server down apart from path broken.

Internal minecraft resolves because uptime-kuma is on mcnet (the container name is the hostname). It is not routed through caddy — caddy only fronts HTTP vhosts, and MC is raw TCP. Do not point the monitor at caddy or any status./pack. alias.

Notes

  • The Minecraft monitor pings TCP 25565; it does not check Simple Voice Chat (24454/udp). Add a separate TCP Port monitor against UDP if you want voice coverage — but Kuma's TCP monitor is TCP-only, so UDP voice has no clean probe; rely on the player report instead.
  • Put both MC monitors on the public status page (Settings → Status Pages) so guests can self-check before pinging you.
  • Optional companion HTTP monitors for the web stack: https://auth.${BASE_DOMAIN}, https://pack.${BASE_DOMAIN}/pack.toml, https://${BASE_DOMAIN} — a red pack.toml here explains client mod-mismatch join failures.