From de75a2ca1dea7ff8336bf34711a7cb413039e853 Mon Sep 17 00:00:00 2001 From: Oier Bravo Urtasun Date: Sun, 24 May 2026 05:57:26 +0200 Subject: [PATCH] docs: update README for .lan, online/airgap modes, party DNS + mDNS Co-Authored-By: Claude Opus 4.7 (1M context) --- README.md | 102 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 57 insertions(+), 45 deletions(-) diff --git a/README.md b/README.md index 383f51c..bd06ff8 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ # Ulicraft Server -Self-hosted modded Minecraft (NeoForge 1.21.1) for a LAN party, designed to run -**fully offline**. Self-hosted auth/skins (Drasl), a packwiz modpack, a guest -landing page, and a transparent mirror of Mojang/launcher assets so guest -laptops need no internet. +Self-hosted modded Minecraft (NeoForge 1.21.1) for a LAN party. Runs **online** +(internet present) or **fully air-gapped** (offline). Self-hosted auth/skins +(Drasl), a packwiz modpack, a guest landing page, and a transparent mirror of +Mojang/launcher/NeoForge assets so guest laptops need no internet. ## Stack @@ -11,67 +11,79 @@ laptops need no internet. |---|---|---| | `minecraft` | itzg/minecraft-server | NeoForge 1.21.1 server, `:25565` | | `drasl` | unmojang/drasl | Yggdrasil auth + skins (password login) | -| `caddy` | caddy:alpine | ingress: landing page, auth/packwiz proxy, asset mirror | -| `dnsmasq` | jpillora/dnsmasq | LAN DNS `*.ulicraft.local` + Minecraft SRV | +| `caddy` | caddy:alpine | ingress: landing, auth/packwiz proxy, asset mirror (`tls internal`) | | `mc-backup` | itzg/mc-backup | world backups every 6h via RCON | -Everything keys off two vars in `.env`: `BASE_DOMAIN` (default `ulicraft.local`) -and `HOST_LAN_IP`. Services are subdomains: `auth.`, `packwiz.`, plus the apex -landing page. +Optional layers: `avahi` (mDNS `.local`), `dnsmasq` (turnkey DNS) — only if you +don't run your own DNS. + +Config lives in `.env`: `BASE_DOMAIN` (default `ulicraft.lan`), `HOST_LAN_IP`, +`RCON_PASSWORD`, `ENABLE_MDNS`. Services are subdomains: `auth.`, `packwiz.`, +`mc.`, plus the apex landing page. + +## DNS (pick one) + +Names must resolve to `HOST_LAN_IP`. Use **your own party DNS server** (recommended): + +```sh +tooling/dns-records.sh online # service names only (internet present) +tooling/dns-records.sh airgap # + Mojang/launcher/NeoForge spoofs (offline) +``` +Paste the printed records into your DNS. **Use `.lan`, not `.local`** — `.local` +is intercepted by mDNS and won't resolve via unicast DNS. + +Alternatives: `ENABLE_MDNS=true` + `BASE_DOMAIN=*.local` (zero-config mDNS, +macOS/Linux native, Windows needs Bonjour) — but mDNS can't serve the air-gap +upstream spoofs. Or layer in `docker-compose.dnsmasq.yml` for a turnkey DNS. ## Prerequisites -Docker + Docker Compose, and for prep: `pnpm`, `packwiz`, `jq`, `curl`, +Docker + Docker Compose; for prep also `pnpm`, `packwiz`, `jq`, `curl`, `envsubst`, `sha1sum`. -## Setup - -```sh -cp .env.example .env # set BASE_DOMAIN, HOST_LAN_IP, RCON_PASSWORD -``` - -Point guest laptops' DNS at `HOST_LAN_IP` (resolves `*.ulicraft.local`). On the -Docker host, free port 53 if `systemd-resolved` holds it (dnsmasq binds the LAN -IP only). - ## Launch ```sh -tooling/build-stack.sh --prep # ONLINE, run once: render configs, build - # landing, mirror mods+assets, fetch - # launcher, pre-bake the server volume +cp .env.example .env # set BASE_DOMAIN, HOST_LAN_IP, RCON_PASSWORD -tooling/build-stack.sh --up [mode] # bring the stack up -# core base only (no static site, no mirror) -# static + apex landing page + launcher downloads -# mirror + full air-gap asset mirror (HTTPS :443) -# full static + mirror (default) +tooling/build-stack.sh --prep # ONLINE, once: render, build landing, + # mirror mods+assets, fetch launcher + + # authlib, pre-bake the server volume + +tooling/build-stack.sh --up online # internet present, no mirror +tooling/build-stack.sh --up airgap # offline; full asset mirror on :443 (default) +tooling/build-stack.sh --up core # base only (debugging) ``` -Down: `docker compose -f docker-compose.yml -f docker-compose.static.yml -f docker-compose.mirror.yml down` +`--up` prints the DNS records to add for that mode. Down: +`docker compose -f docker-compose.yml -f docker-compose.static.yml -f docker-compose.mirror.yml down` ## Join (guests) -1. Open `http://ulicraft.local`, download FjordLauncherUnlocked for your OS. -2. Add an **authlib-injector** account, URL `http://auth.ulicraft.local/authlib-injector` - (register/login at `http://auth.ulicraft.local`). -3. (Air-gap) Trust the Caddy root CA; in Settings → APIs set **Assets Server** - to the mirror if not using DNS spoofing. -4. Import the pack: `http://packwiz.ulicraft.local/pack.toml`. -5. Connect to **`mc.ulicraft.local`** (no port — SRV record). +1. Open `http://ulicraft.lan`, download FjordLauncherUnlocked for your OS. +2. Add an **authlib-injector** account, URL `http://auth.ulicraft.lan/authlib-injector` + (register/login at `http://auth.ulicraft.lan`). +3. **Air-gap only:** trust the local CA — download `http://ulicraft.lan/ca.crt` + and add it to your OS trust store (so the HTTPS asset mirror is trusted). +4. Import the pack: `http://packwiz.ulicraft.lan/pack.toml`. +5. Connect to **`mc.ulicraft.lan`** (no port needed). ## Layout ``` -docker-compose.yml + .static.yml + .mirror.yml # core + optional layers -caddy/Caddyfile + conf.d/*.caddy # ingress vhost snippets -drasl/config/config.toml.tmpl # auth config (rendered) -dnsmasq/dnsmasq.conf.tmpl # LAN DNS + SRV (rendered) -pack/ # packwiz modpack source -landing/ # Astro site → www/ -tooling/ # build-stack + render/mirror/fetch scripts -mirror/ # vendored jars + launcher + asset mirror (gitignored) -plan/ # full design docs (00–12) +docker-compose.yml # core: drasl, minecraft, mc-backup, caddy + .static.yml .mirror.yml # online/airgap layers + .avahi.yml .dnsmasq.yml # optional DNS layers +caddy/Caddyfile + conf.d/*.caddy # ingress vhost snippets (core/static/mirror) +drasl/config/config.toml.tmpl # auth config (rendered) +dnsmasq/dnsmasq.conf.tmpl # optional DNS config (rendered) +docker/avahi/ # mDNS responder image +pack/ # packwiz modpack source +landing/ # Astro site → www/ +tooling/ # build-stack, render-config, dns-records, + # mirror-mods, mirror-airgap, fetch-launcher +mirror/ # vendored jars + launcher + asset mirror (gitignored) +plan/ # full design docs (00–12) ``` See `plan/00-overview.md` for the full design.