Propagate the bare-hostname fix (10b86ae) to the docs that still said "three
traps", and write down the meta-lesson it exposed.
The bug was invisible to every check we had: Filestash strips the scheme
before its own Host check, so `curl /` returned 200, the API answered, wrong
passwords were rejected, and the brand-new Uptime Kuma HTTP monitor stayed
green — while the SPA computed `http://https://files...` and no browser could
use the site. An HTTP monitor asserts "server returned 200", which is a much
weaker claim than "the app works".
- CLAUDE.md / README: four traps now, host-scheme first; add the post-change
check (`/api/config` → origin must be the real https URL).
- 19-routes: login form only renders at ?action=redirect (a bare 303 is
normal, not a bug); assert origin after config changes.
- 10-uptime-kuma: an HTTP monitor cannot see an SPA break — use a Keyword
monitor if you want teeth, and don't read green as "users can log in".
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
3.2 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 pingminecraftovermcnetbut 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.
- Open
https://status.${BASE_DOMAIN}and log in (admin account created on first run). - + Add New Monitor.
- Monitor Type:
Minecraft Server. - Fill in one of the two probe targets below.
- Heartbeat Interval:
60s (fine for a friends' server). - Retries:
2, Retry Interval:30s — avoids flapping on a GC pause. - 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
minecraftresolves because uptime-kuma is onmcnet(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 atcaddyor anystatus.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://distribution.${BASE_DOMAIN},https://${BASE_DOMAIN},https://files.${BASE_DOMAIN}— a reddistribution.here explains client mod-mismatch join failures.
An HTTP monitor cannot see an SPA break. It asserts "the server returned 200", which is a much weaker claim than "the app works".
files.(Filestash) proved this on 2026-07-14: a badgeneral.hostmade every client-side redirect resolve tohttp://https://files…, so the site was unusable in every browser while/kept returning 200 and the monitor stayed green. If you want a monitor with teeth on a JS app, use Kuma's Keyword type against a string the rendered page must contain, and don't read green as "users can log in".