Commit Graph
4 Commits
Author SHA1 Message Date
oierandClaude Opus 5 fca6747bcc feat(monitor): admin-only latest.log stream at monitor.
Phase 1 of plan/23-monitor.md: a small Go service that tails the Minecraft
server's latest.log into an in-memory ring buffer and serves it to an embedded
single-page UI (autoscroll, substring/regex filter, level chips).

Read-only by construction — /data is mounted :ro, there is no mutating route,
and the container holds no credentials. It publishes NO port: caddy's
basic_auth vhost is the only way in, which is the point, since the service has
no auth of its own and the log carries player IPs, chat and admin commands.

Two non-obvious choices, both to avoid prod-only failures:

- Polling, not SSE. The chain is host nginx -> caddy -> app, and nginx buffers
  proxied responses by default, so an EventSource would stall on cochi (whose
  vhost is an untracked per-host file) and not reproduce locally. Delay was
  accepted at design time, so polling is strictly better.

- The cursor is a sequence number, not a byte offset, and the tailer reopens on
  inode change or size shrink. itzg rotates latest.log on every server restart,
  i.e. every deploy — a naive tailer goes silent afterwards while still
  answering HTTP 200. Verified against rotate, truncate, delete/recreate,
  partial-line and ring-overflow cases.

MONITOR_ENABLED (on|off) gates both layers per host, mirroring FILES_BROWSE.

MONITOR_PASSWORD_HASH must be bcrypt AND single-quoted in .env: Compose
interpolates $-sequences in .env values, so a bare hash is silently mangled
($2a$14$abc... -> $$2a$$14...) and every login fails with no hint why.
Confirmed empirically, and it is the opposite of filestash, which needs $6$.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-01 22:51:39 +02:00
oierandClaude Opus 5 8507ffd020 feat(files): gate files. browse behind FILES_BROWSE (on|off)
Per-host toggle for the read-only, no-auth browse of the shared upload dir,
so it can stay on for the LAN-party host (oxps) and be off on the
internet-facing one (cochi). Defaults to `on` — existing hosts unchanged.

Neither layer has conditionals, so each gets the value substituted in:
- caddy: docker-compose mounts 62-files.${FILES_BROWSE:-on}.caddy at the
  fixed conf.d target (62-files.caddy -> 62-files.on.caddy, plus a
  comments-only 62-files.off.caddy stub — caddy needs a parseable file
  there). Same trick as FILES_MOUNT_MODE.
- nginx: render-nginx.sh splices nginx/files-browse.server.tmpl into
  ${FILES_BROWSE_SERVER} and adds/omits the name in the port-80 redirect.
  This is the gate that matters; caddy is bound to 127.0.0.1.

Applying a change needs render-nginx.sh --install plus a caddy
--force-recreate (single-file bind mount pins the inode). With `off`,
drop `files` from LE_SUBDOMAINS on that host. upload. is unaffected.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 17:08:33 +02:00
oierandClaude Opus 4.8 67d1f82e6a refactor!: unify into one compose, drop airgap/mirror/dnsmasq/avahi/blessingskin
Collapse the override-file matrix into a single docker-compose.yml holding the
whole stack: drasl, minecraft, mc-backup, caddy, nmsr, uptime-kuma. Bring-up is
now just `docker compose up -d --build`.

Removed features (dead-ends for this deployment):
- airgap / full asset mirror (mirror-airgap.sh, mirror-mods.sh, 20-mirror.caddy,
  caddy local-CA export, /ca.crt)
- dnsmasq + avahi/mDNS + dns-records.sh + mdns-host-setup.sh + ENABLE_MDNS;
  DNS is now handled outside this repo (HOST_LAN_IP dropped)
- Blessing Skin auth variant (compose + 00-core-blessingskin.caddy + BS_* env)
- host-nginx-static variant (docker-compose.nginx.yml, nginx/ulicraft.conf.tmpl)
- build-stack.sh and its run modes (online/airgap/core)

Production ingress is the only path now: host nginx terminates TLS (LE certs)
in front of caddy on a localhost-only port; caddy routes every vhost by Host
header. Launcher downloads move mirror/launcher -> launcher/.

Docs: README, deploy skill, and plan/ rewritten to match; obsolete plan docs
(dnsmasq, blessing-skin, assets-mirror, full-airgap-mirror, dns-and-run-modes)
deleted.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 02:14:09 +02:00
oierandClaude Opus 4.8 3185fea4c1 feat(nginx): render-nginx.sh + www->apex redirect vhost
Add tooling/render-nginx.sh: pulls BASE_DOMAIN/CADDY_HTTP_PORT from .env,
defaults APP_DIR to the repo checkout, renders a vhost template (default the
caddy-front one) to stdout, or --install writes + symlinks + nginx -t + reloads.
Document it in the README, replacing the manual envsubst one-liner.

Also add the www.${BASE_DOMAIN} canonical 301->apex block and put www in the
LE_SUBDOMAINS default so its cert is issued.

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