From 4ddf36cefd058949b48716887be226abe3a30055 Mon Sep 17 00:00:00 2001 From: Oier Bravo Urtasun Date: Sun, 24 May 2026 05:10:44 +0200 Subject: [PATCH] docs: add README (stack summary + launch instructions) Co-Authored-By: Claude Opus 4.7 (1M context) --- README.md | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..383f51c --- /dev/null +++ b/README.md @@ -0,0 +1,77 @@ +# 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. + +## Stack + +| Service | Image | Role | +|---|---|---| +| `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 | +| `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. + +## Prerequisites + +Docker + Docker Compose, and for prep: `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 + +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) +``` + +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). + +## 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) +``` + +See `plan/00-overview.md` for the full design.