Files
ulicraft-server-v1/README.md
2026-05-24 05:57:26 +02:00

90 lines
3.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Ulicraft Server
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
| 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, auth/packwiz proxy, asset mirror (`tls internal`) |
| `mc-backup` | itzg/mc-backup | world backups every 6h via RCON |
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; for prep also `pnpm`, `packwiz`, `jq`, `curl`,
`envsubst`, `sha1sum`.
## Launch
```sh
cp .env.example .env # set BASE_DOMAIN, HOST_LAN_IP, RCON_PASSWORD
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)
```
`--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.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 # 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 (0012)
```
See `plan/00-overview.md` for the full design.