chore: remove pack (packwiz) service and subdomain

The pack service was already gone from compose/caddy and the landing is
off packwiz. Remove the remaining live references: the pack. TLS vhost in
the host nginx template, pack from LE_SUBDOMAINS, and stale docs in README
and CLAUDE.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-11 09:38:28 +02:00
parent 7222904c91
commit 14ef545bbb
4 changed files with 19 additions and 41 deletions

View File

@@ -2,7 +2,7 @@
# Single base domain for the whole stack; every service is a subdomain of this. # Single base domain for the whole stack; every service is a subdomain of this.
# DNS is handled OUTSIDE this repo — point ${BASE_DOMAIN} and every subdomain # DNS is handled OUTSIDE this repo — point ${BASE_DOMAIN} and every subdomain
# (auth. pack. avatar. status. distribution. www.) at the host running nginx. # (auth. avatar. status. distribution. www.) at the host running nginx.
BASE_DOMAIN=ulicraft.net BASE_DOMAIN=ulicraft.net
RCON_PASSWORD=change-me-to-something-random RCON_PASSWORD=change-me-to-something-random
@@ -56,7 +56,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. # Only needed to issue real TLS certs. DNS-01 needs no inbound ports.
LE_EMAIL=you@example.com LE_EMAIL=you@example.com
# space-separated subdomains; apex ${BASE_DOMAIN} is always included # space-separated subdomains; apex ${BASE_DOMAIN} is always included
LE_SUBDOMAINS=auth pack distribution www avatar status LE_SUBDOMAINS=auth distribution www avatar status
# OVH API creds (DNS zone write). Create at https://eu.api.ovh.com/createToken/ # 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_CK can be blank on first run — acme.sh prints an auth URL, then paste it.
OVH_END_POINT=ovh-eu OVH_END_POINT=ovh-eu

View File

@@ -23,7 +23,7 @@ with `plan/` or the code, those win.
One unified `docker-compose.yml`. The host's own nginx terminates TLS (Let's One unified `docker-compose.yml`. The host's own nginx terminates TLS (Let's
Encrypt) and reverse-proxies every vhost to caddy (published localhost-only) by Encrypt) and reverse-proxies every vhost to caddy (published localhost-only) by
Host header. caddy is the internal router; containers reach the stack's own names Host header. caddy is the internal router; containers reach the stack's own names
via caddy's `mcnet` aliases (`auth.`, `pack.`). via caddy's `mcnet` aliases (`auth.`).
``` ```
Internet ── host nginx (TLS, LE certs, HSTS) ──► caddy (127.0.0.1:8880) Internet ── host nginx (TLS, LE certs, HSTS) ──► caddy (127.0.0.1:8880)
@@ -119,8 +119,7 @@ mirrored at apex `/launcher/`. Per guest:
`https://auth.${BASE_DOMAIN}/authlib-injector` (register/login at `https://auth.${BASE_DOMAIN}/authlib-injector` (register/login at
`https://auth.${BASE_DOMAIN}`). `https://auth.${BASE_DOMAIN}`).
3. The launcher installs the modpack from the distribution (`distribution.json`). 3. The launcher installs the modpack from the distribution (`distribution.json`).
(NOTE: packwiz/`pack.` removed — the landing join step still references a (packwiz and the `pack.` service/subdomain have been fully removed.)
packwiz URL and needs reworking around the launcher/distribution flow.)
4. Connect to `${BASE_DOMAIN}` (`:25565`). 4. Connect to `${BASE_DOMAIN}` (`:25565`).
## Open / Pending Work ## Open / Pending Work

View File

@@ -1,9 +1,9 @@
# Ulicraft Server # Ulicraft Server
Self-hosted modded Minecraft (NeoForge 1.21.1) with self-hosted auth/skins Self-hosted modded Minecraft (NeoForge 1.21.1) with self-hosted auth/skins
(Drasl), a packwiz modpack, avatar rendering, a guest landing page, and uptime (Drasl), a distribution-fed modpack, avatar rendering, a guest landing page, and
monitoring. One unified `docker-compose.yml` runs the whole stack behind the uptime monitoring. One unified `docker-compose.yml` runs the whole stack behind
host's nginx + Let's Encrypt. the host's nginx + Let's Encrypt.
## Stack ## Stack
@@ -22,7 +22,6 @@ Vhosts (all proxied through the host nginx → caddy):
- apex `${BASE_DOMAIN}` — landing page + `/launcher/` downloads - apex `${BASE_DOMAIN}` — landing page + `/launcher/` downloads
- `auth.` — Drasl - `auth.` — Drasl
- `pack.` — packwiz metadata + `/custom/` jars
- `avatar.` — NMSR - `avatar.` — NMSR
- `status.` — Uptime Kuma - `status.` — Uptime Kuma
- `distribution.` — static site from another repo (`DISTRIBUTION_WEB_ROOT`) - `distribution.` — static site from another repo (`DISTRIBUTION_WEB_ROOT`)
@@ -33,12 +32,11 @@ Config lives in `.env`: `BASE_DOMAIN`, `RCON_PASSWORD`, `CADDY_HTTP_PORT` /
## DNS ## DNS
Handled **outside this repo**. Point `${BASE_DOMAIN}` and every subdomain Handled **outside this repo**. Point `${BASE_DOMAIN}` and every subdomain
(`auth. pack. avatar. status. distribution. www.`) at the host running nginx. (`auth. avatar. status. distribution. www.`) at the host running nginx.
## Prerequisites ## Prerequisites
Docker + Docker Compose; for prep also `pnpm`, `packwiz`, `jq`, `curl`, Docker + Docker Compose; for prep also `pnpm`, `jq`, `curl`, `envsubst`.
`envsubst`.
## Launch ## Launch
@@ -46,7 +44,8 @@ Docker + Docker Compose; for prep also `pnpm`, `packwiz`, `jq`, `curl`,
cp .env.example .env # set BASE_DOMAIN, RCON_PASSWORD, DISTRIBUTION_WEB_ROOT cp .env.example .env # set BASE_DOMAIN, RCON_PASSWORD, DISTRIBUTION_WEB_ROOT
# One-time / on change — render configs + build content: # One-time / on change — render configs + build content:
tooling/render-config.sh # drasl + nmsr + packwiz configs from *.tmpl tooling/render-config.sh # drasl + nmsr configs from *.tmpl
tooling/sync-server-mods.sh # filtered server mods → ./server-mods
( cd landing && pnpm install && BASE_DOMAIN="$BASE_DOMAIN" pnpm run build ) # → www/ ( cd landing && pnpm install && BASE_DOMAIN="$BASE_DOMAIN" pnpm run build ) # → www/
tooling/fetch-launcher.sh # FjordLauncher assets → launcher/ (served at /launcher/) tooling/fetch-launcher.sh # FjordLauncher assets → launcher/ (served at /launcher/)
tooling/fetch-authlib.sh # authlib-injector.jar → runtime/ (server JVM agent) tooling/fetch-authlib.sh # authlib-injector.jar → runtime/ (server JVM agent)
@@ -55,7 +54,7 @@ docker compose up -d --build # first run installs NeoForge + mods, builds nms
docker compose down # stop docker compose down # stop
``` ```
First boot: itzg installs NeoForge + the packwiz mods into the `mc_data` volume; First boot: itzg installs NeoForge + the synced server mods into the `mc_data` volume;
nmsr does a one-time Rust compile. Watch `docker compose logs -f minecraft` until nmsr does a one-time Rust compile. Watch `docker compose logs -f minecraft` until
`Done`. `Done`.
@@ -69,7 +68,7 @@ certs and reverse-proxies every vhost to caddy by Host header. HTTPS-only: HTTP
1. **Issue certs** (OVH DNS-01, no inbound ports needed): 1. **Issue certs** (OVH DNS-01, no inbound ports needed):
```sh ```sh
# .env: BASE_DOMAIN, LE_EMAIL, OVH_* creds, # .env: BASE_DOMAIN, LE_EMAIL, OVH_* creds,
# LE_SUBDOMAINS="auth pack distribution www avatar status" # LE_SUBDOMAINS="auth distribution www avatar status"
tooling/issue-letsencrypt.sh # → certs/<name>/{cert,key}.pem tooling/issue-letsencrypt.sh # → certs/<name>/{cert,key}.pem
``` ```
@@ -120,7 +119,6 @@ persists in the `kuma_data` volume):
| Minecraft | Minecraft Server | `minecraft` : `25565` | | Minecraft | Minecraft Server | `minecraft` : `25565` |
| Drasl auth | HTTP(s) | `https://auth.${BASE_DOMAIN}` | | Drasl auth | HTTP(s) | `https://auth.${BASE_DOMAIN}` |
| Landing (apex) | HTTP(s) | `https://${BASE_DOMAIN}` | | Landing (apex) | HTTP(s) | `https://${BASE_DOMAIN}` |
| Packwiz | HTTP(s) | `https://pack.${BASE_DOMAIN}` |
| Distribution | HTTP(s) | `https://distribution.${BASE_DOMAIN}` | | Distribution | HTTP(s) | `https://distribution.${BASE_DOMAIN}` |
| Avatar (NMSR) | HTTP(s) | `https://avatar.${BASE_DOMAIN}` | | Avatar (NMSR) | HTTP(s) | `https://avatar.${BASE_DOMAIN}` |
@@ -161,7 +159,7 @@ Wired in `landing/src/data/site.ts` (`statusApi`) and `caddy/conf.d/10-static.ca
2. Add an **authlib-injector** account, URL 2. Add an **authlib-injector** account, URL
`https://auth.${BASE_DOMAIN}/authlib-injector` (register/login at `https://auth.${BASE_DOMAIN}/authlib-injector` (register/login at
`https://auth.${BASE_DOMAIN}`). `https://auth.${BASE_DOMAIN}`).
3. Import the pack: `https://pack.${BASE_DOMAIN}/pack.toml`. 3. The launcher installs the modpack from the distribution automatically.
4. Connect to **`${BASE_DOMAIN}`** (Minecraft, `:25565`). 4. Connect to **`${BASE_DOMAIN}`** (Minecraft, `:25565`).
## Layout ## Layout
@@ -173,11 +171,11 @@ caddy/Caddyfile + conf.d/*.caddy # ingress vhost snippets
drasl/config/config.toml.tmpl # auth config (rendered) drasl/config/config.toml.tmpl # auth config (rendered)
nmsr/config.toml.tmpl # avatar renderer config, Drasl-backed (rendered) nmsr/config.toml.tmpl # avatar renderer config, Drasl-backed (rendered)
docker/nmsr/ # built-from-source NMSR image docker/nmsr/ # built-from-source NMSR image
pack/ # packwiz modpack source
landing/ # Astro site → www/ landing/ # Astro site → www/
launcher/ # FjordLauncher assets (gitignored) launcher/ # FjordLauncher assets (gitignored)
tooling/ # render-config, render-pack, render-nginx, server-mods/ # filtered server mod jars (synced, gitignored)
# issue-letsencrypt, fetch-launcher, add-custom-mod tooling/ # render-config, sync-server-mods, render-nginx,
# issue-letsencrypt, fetch-launcher
nginx/ulicraft-caddy.conf.tmpl # host-nginx TLS vhost template (front of caddy) nginx/ulicraft-caddy.conf.tmpl # host-nginx TLS vhost template (front of caddy)
plan/ # design docs plan/ # design docs
``` ```

View File

@@ -30,13 +30,12 @@ upstream ulicraft_caddy {
server { server {
listen 80; listen 80;
listen [::]:80; listen [::]:80;
server_name ${BASE_DOMAIN} www.${BASE_DOMAIN} auth.${BASE_DOMAIN} pack.${BASE_DOMAIN} distribution.${BASE_DOMAIN} avatar.${BASE_DOMAIN} status.${BASE_DOMAIN}; server_name ${BASE_DOMAIN} www.${BASE_DOMAIN} auth.${BASE_DOMAIN} distribution.${BASE_DOMAIN} avatar.${BASE_DOMAIN} status.${BASE_DOMAIN};
return 301 https://$host$request_uri; return 301 https://$host$request_uri;
} }
# One TLS server block per name (each has its own LE cert). All proxy to caddy; # One TLS server block per name (each has its own LE cert). All proxy to caddy;
# caddy routes by the forwarded Host header (apex -> www, auth -> drasl, # caddy routes by the forwarded Host header (apex -> www, auth -> drasl).
# pack -> packwiz files).
server { server {
listen 443 ssl http2; listen 443 ssl http2;
listen [::]:443 ssl http2; listen [::]:443 ssl http2;
@@ -90,24 +89,6 @@ server {
} }
} }
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name pack.${BASE_DOMAIN};
ssl_certificate ${APP_DIR}/certs/pack.${BASE_DOMAIN}/cert.pem;
ssl_certificate_key ${APP_DIR}/certs/pack.${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;
}
}
server { server {
listen 443 ssl http2; listen 443 ssl http2;
listen [::]:443 ssl http2; listen [::]:443 ssl http2;