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>
64 lines
3.2 KiB
Markdown
64 lines
3.2 KiB
Markdown
# 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.` 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 red
|
|
`distribution.` 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 bad `general.host` made every client-side redirect
|
|
> resolve to `http://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".
|