From 673202e1e4d96b216b533d1c411606dfb5456622 Mon Sep 17 00:00:00 2001 From: Oier Bravo Urtasun Date: Tue, 9 Jun 2026 04:11:53 +0200 Subject: [PATCH] fix(compose): pin auth./pack. to host-gateway so HTTPS resolves in-container Containers don't inherit the host's /etc/hosts; the LAN resolver returns a dead address (192.168.0.3:443) for the public names, crash-looping the packwiz install on boot. extra_hosts host-gateway routes HTTPS through the host's nginx (valid LE cert) -> caddy -> service. Also add plan/10-uptime-kuma.md (Minecraft monitor: internal + public probes) and document the HTTPS resolution variant in plan/00-overview.md. Co-Authored-By: Claude Opus 4.8 (1M context) --- docker-compose.yml | 6 +++++ plan/00-overview.md | 24 ++++++++++++++++++++ plan/10-uptime-kuma.md | 51 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+) create mode 100644 plan/10-uptime-kuma.md diff --git a/docker-compose.yml b/docker-compose.yml index 8850fb1..8e5ac9f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -86,6 +86,12 @@ services: depends_on: - drasl - caddy # pack./auth. must resolve at boot + # Containers don't inherit the host's /etc/hosts; the LAN resolver returns a + # dead address for the public names. Pin auth./pack. to the host so HTTPS to + # them lands on the host's nginx (valid LE cert) -> caddy -> service. + extra_hosts: + - "auth.${BASE_DOMAIN}:host-gateway" + - "pack.${BASE_DOMAIN}:host-gateway" networks: - mcnet diff --git a/plan/00-overview.md b/plan/00-overview.md index a27a3e4..de5f7ed 100644 --- a/plan/00-overview.md +++ b/plan/00-overview.md @@ -52,6 +52,30 @@ Result: `http://auth.ulicraft.net/authlib-injector` and `http://pack.ulicraft.net/pack.toml` resolve identically inside the stack (minecraft → caddy) as the public names do outside it (client → nginx → caddy). +#### HTTPS variant (`extra_hosts: host-gateway`) + +The caddy alias only serves **http** on `mcnet` (port 80). Once the stack moved +to https URLs (drasl `BaseURL`, `PACKWIZ_URL`, the authlib-injector agent must +match the client's https endpoint), the internal http alias is no longer enough — +the container needs to reach a **TLS** terminator holding a valid cert. + +Caddy does not terminate TLS internally; the host's nginx does (on `0.0.0.0:443`). +So pin the public names to the host in the service, not to caddy: + +```yaml +minecraft: + extra_hosts: + - "auth.${BASE_DOMAIN}:host-gateway" + - "pack.${BASE_DOMAIN}:host-gateway" +``` + +`/etc/hosts` (extra_hosts) wins over the Docker resolver, so the container reaches +the host's nginx (valid LE cert) → caddy → service. This is required because +**containers do not inherit the host's `/etc/hosts`** — on cochi the host resolves +`auth./pack.` to the public IP, but inside a container the LAN resolver returns a +dead address (`192.168.0.3:443`, connection refused), which crash-loops the +packwiz install on boot. `host-gateway` sidesteps DNS entirely. + ## Build / run flow ``` diff --git a/plan/10-uptime-kuma.md b/plan/10-uptime-kuma.md new file mode 100644 index 0000000..f6942ab --- /dev/null +++ b/plan/10-uptime-kuma.md @@ -0,0 +1,51 @@ +# 10 — Uptime Kuma + +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.