feat(status): Uptime Kuma monitoring at status.${BASE_DOMAIN}
Add docker-compose.status.yml (louislam/uptime-kuma) layered on the caddy ingress, joining mcnet so it probes the stack by internal service name and the public vhosts end-to-end. Host port bound to 127.0.0.1:3001 only; public access via nginx -> caddy. - caddy/conf.d/50-status.caddy: status. -> uptime-kuma:3001 - nginx caddy-front template: status. TLS vhost + websocket upgrade headers for Kuma's live UI; status. added to the HTTP->HTTPS redirect list - status added to LE_SUBDOMAINS defaults (.env.example, issue-letsencrypt.sh) - README: Status monitoring section + recommended monitor list (incl. native Minecraft-protocol ping) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -37,7 +37,7 @@ DISTRIBUTION_WEB_ROOT=/home/oier/projects/mc-mods/ulicraft-group/ulicraft-distri
|
||||
# Only needed to issue real TLS certs. DNS-01 needs no inbound ports.
|
||||
LE_EMAIL=you@example.com
|
||||
# space-separated subdomains; apex ${BASE_DOMAIN} is always included
|
||||
LE_SUBDOMAINS=auth pack distribution www avatar
|
||||
LE_SUBDOMAINS=auth pack distribution www avatar status
|
||||
# OVH API creds (DNS zone write). Create at https://eu.api.ovh.com/createToken/
|
||||
# OVH_CK can be blank on first run — acme.sh prints an auth URL, then paste it.
|
||||
OVH_END_POINT=ovh-eu
|
||||
|
||||
40
README.md
40
README.md
@@ -21,6 +21,8 @@ Optional layers (each its own `docker-compose.<name>.yml`):
|
||||
`avatar.${BASE_DOMAIN}`, sourced from Drasl. See **Avatar renderer** below.
|
||||
- `distribution` — extra static vhost at `distribution.${BASE_DOMAIN}` whose web
|
||||
root (`DISTRIBUTION_WEB_ROOT`) lives in another repo.
|
||||
- `status` (louislam/uptime-kuma) — uptime monitoring + public status page at
|
||||
`status.${BASE_DOMAIN}`. See **Status monitoring** below.
|
||||
|
||||
Config lives in `.env`: `BASE_DOMAIN` (default `ulicraft.lan`), `HOST_LAN_IP`,
|
||||
`RCON_PASSWORD`, `ENABLE_MDNS`. Services are subdomains: `auth.`, `packwiz.`,
|
||||
@@ -96,7 +98,7 @@ nmsr). HTTPS-only: HTTP 301s to HTTPS and every TLS vhost sends HSTS.
|
||||
1. **Issue certs** (OVH DNS-01, no inbound ports needed):
|
||||
```sh
|
||||
# .env: BASE_DOMAIN, LE_EMAIL, OVH_* creds,
|
||||
# LE_SUBDOMAINS="auth pack distribution www avatar"
|
||||
# LE_SUBDOMAINS="auth pack distribution www avatar status"
|
||||
tooling/issue-letsencrypt.sh # → certs/<name>/{cert,key}.pem
|
||||
```
|
||||
|
||||
@@ -110,7 +112,7 @@ nmsr). HTTPS-only: HTTP 301s to HTTPS and every TLS vhost sends HSTS.
|
||||
```sh
|
||||
docker compose -f docker-compose.yml -f docker-compose.caddy.yml \
|
||||
-f docker-compose.static.yml -f docker-compose.distribution.yml \
|
||||
-f docker-compose.nmsr.yml up -d --build
|
||||
-f docker-compose.nmsr.yml -f docker-compose.status.yml up -d --build
|
||||
```
|
||||
|
||||
4. **Render + install the nginx vhost** with `tooling/render-nginx.sh`. It pulls
|
||||
@@ -153,6 +155,40 @@ Vulkan); if renders fail, check `docker logs nmsr` for Vulkan device init.
|
||||
another repo: set `DISTRIBUTION_WEB_ROOT` (absolute host path) in `.env`; it's
|
||||
bind-mounted read-only via `docker-compose.distribution.yml`.
|
||||
|
||||
## Status monitoring (Uptime Kuma)
|
||||
|
||||
`status.${BASE_DOMAIN}` runs [Uptime Kuma](https://github.com/louislam/uptime-kuma)
|
||||
— uptime probes for every vhost **and** a native Minecraft-protocol ping (player
|
||||
count + up/down), plus a public status page. The container joins `mcnet`, so it
|
||||
can probe the stack by internal service name without leaving the host. caddy
|
||||
reverse-proxies `status.` → `uptime-kuma:3001`; the host port is published on
|
||||
`127.0.0.1:3001` only (first-run admin setup / local debugging).
|
||||
|
||||
Bring up (layer on the caddy ingress):
|
||||
|
||||
```sh
|
||||
docker compose -f docker-compose.yml -f docker-compose.caddy.yml \
|
||||
-f docker-compose.status.yml up -d
|
||||
```
|
||||
|
||||
Then open `https://status.${BASE_DOMAIN}` (or `http://127.0.0.1:3001` first run),
|
||||
create the admin account, and add monitors. Kuma has no config-as-code — add
|
||||
these once via the UI (data persists in the `kuma_data` volume):
|
||||
|
||||
| Monitor | Type | Target |
|
||||
|---|---|---|
|
||||
| Minecraft | Minecraft Server | `minecraft` : `25565` |
|
||||
| Drasl auth | HTTP(s) | `https://auth.${BASE_DOMAIN}` |
|
||||
| Landing (apex) | HTTP(s) | `https://${BASE_DOMAIN}` |
|
||||
| Packwiz | HTTP(s) | `https://pack.${BASE_DOMAIN}` |
|
||||
| Distribution | HTTP(s) | `https://distribution.${BASE_DOMAIN}` |
|
||||
| Avatar (NMSR) | HTTP(s) | `https://avatar.${BASE_DOMAIN}` |
|
||||
|
||||
Internal-name targets (`minecraft`, `drasl:25585`, `nmsr:8080`) isolate "service
|
||||
down" from "ingress/TLS/DNS down"; public-URL targets test the whole chain. Mix
|
||||
as you like. `status` is in the default `LE_SUBDOMAINS` so its TLS cert issues
|
||||
with the rest; the nginx vhost adds websocket upgrade headers for Kuma's live UI.
|
||||
|
||||
## Join (guests)
|
||||
|
||||
1. Open `http://ulicraft.lan`, download FjordLauncherUnlocked for your OS.
|
||||
|
||||
5
caddy/conf.d/50-status.caddy
Normal file
5
caddy/conf.d/50-status.caddy
Normal file
@@ -0,0 +1,5 @@
|
||||
# Status toggle — Uptime Kuma monitoring + public status page
|
||||
# (docker-compose.status.yml). Mounted only when the status override is present.
|
||||
http://status.{$BASE_DOMAIN} {
|
||||
reverse_proxy uptime-kuma:3001
|
||||
}
|
||||
36
docker-compose.status.yml
Normal file
36
docker-compose.status.yml
Normal file
@@ -0,0 +1,36 @@
|
||||
# ──────────────────────────────────────────────────────────────────
|
||||
# Uptime Kuma — status/monitoring for every vhost + the Minecraft server,
|
||||
# reachable at status.${BASE_DOMAIN}.
|
||||
# ──────────────────────────────────────────────────────────────────
|
||||
# docker compose -f docker-compose.yml -f docker-compose.caddy.yml \
|
||||
# -f docker-compose.status.yml up -d
|
||||
#
|
||||
# Joins mcnet so monitors can probe the stack BY ITS INTERNAL SERVICE NAME
|
||||
# (drasl:25585, nmsr:8080, minecraft:25565) without leaving the host — and can
|
||||
# also hit the public https vhosts end-to-end through the host's DNS.
|
||||
#
|
||||
# Caddy reverse-proxies status.${BASE_DOMAIN} -> uptime-kuma:3001 internally
|
||||
# (caddy/conf.d/50-status.caddy). The host port is published on 127.0.0.1:3001
|
||||
# ONLY (local debugging / first-run admin setup) — public access goes through
|
||||
# nginx -> caddy. Add status.${BASE_DOMAIN} to LE_SUBDOMAINS for its TLS cert.
|
||||
#
|
||||
# Monitors are stored in the kuma_data volume (Kuma has no config-as-code);
|
||||
# add them once via the web UI — see README for the recommended monitor list.
|
||||
services:
|
||||
caddy:
|
||||
volumes:
|
||||
- ./caddy/conf.d/50-status.caddy:/etc/caddy/conf.d/50-status.caddy:ro
|
||||
|
||||
uptime-kuma:
|
||||
image: louislam/uptime-kuma:1
|
||||
container_name: uptime-kuma
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "127.0.0.1:3001:3001"
|
||||
volumes:
|
||||
- kuma_data:/app/data
|
||||
networks:
|
||||
- mcnet
|
||||
|
||||
volumes:
|
||||
kuma_data:
|
||||
@@ -32,7 +32,7 @@ upstream ulicraft_caddy {
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name ${BASE_DOMAIN} www.${BASE_DOMAIN} auth.${BASE_DOMAIN} pack.${BASE_DOMAIN} distribution.${BASE_DOMAIN} avatar.${BASE_DOMAIN};
|
||||
server_name ${BASE_DOMAIN} www.${BASE_DOMAIN} auth.${BASE_DOMAIN} pack.${BASE_DOMAIN} distribution.${BASE_DOMAIN} avatar.${BASE_DOMAIN} status.${BASE_DOMAIN};
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
|
||||
@@ -145,3 +145,26 @@ server {
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
listen [::]:443 ssl http2;
|
||||
server_name status.${BASE_DOMAIN};
|
||||
|
||||
ssl_certificate ${APP_DIR}/certs/status.${BASE_DOMAIN}/cert.pem;
|
||||
ssl_certificate_key ${APP_DIR}/certs/status.${BASE_DOMAIN}/key.pem;
|
||||
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
|
||||
|
||||
location / {
|
||||
proxy_pass http://ulicraft_caddy;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
# Uptime Kuma uses websockets (socket.io) for live status updates.
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
# OVH_CK OVH consumer key (obtained on first run — see below)
|
||||
# OVH_END_POINT OVH API endpoint (e.g. ovh-eu)
|
||||
# optional:
|
||||
# LE_SUBDOMAINS space-separated (default: "auth pack distribution www avatar")
|
||||
# LE_SUBDOMAINS space-separated (default: "auth pack distribution www avatar status")
|
||||
# LE_STAGING=1 use the LE staging CA (untrusted, for dry runs)
|
||||
#
|
||||
# First-time OVH consumer key: set OVH_AK/OVH_AS/OVH_END_POINT, leave OVH_CK
|
||||
@@ -53,7 +53,7 @@ ACME="${ACME_SH:-$HOME/.acme.sh/acme.sh}"
|
||||
then re-run (or set ACME_SH=/path/to/acme.sh)."
|
||||
|
||||
CERT_DIR="${CERT_DIR:-certs}"
|
||||
read -r -a SUBDOMAINS <<< "${LE_SUBDOMAINS:-auth pack distribution www avatar}"
|
||||
read -r -a SUBDOMAINS <<< "${LE_SUBDOMAINS:-auth pack distribution www avatar status}"
|
||||
|
||||
if [ "${LE_STAGING:-0}" = "1" ]; then
|
||||
SERVER="letsencrypt_test"; warn "STAGING mode — certs will NOT be trusted by browsers"
|
||||
|
||||
Reference in New Issue
Block a user