feat(mods): replace packwiz with distribution-fed custom mod volume
Drop packwiz entirely. The server now loads a filtered mod subset from a local ./server-mods volume instead of fetching a packwiz pack at boot. New flow: - tooling/classify-mods.py (tomllib only, no network) reads each jar's META-INF/neoforge.mods.toml and seeds mods-sides.json with a side (client|server|both; default both). Existing entries are preserved. - mods-sides.json: committed, keyed by jar filename, hand-editable override surface. Initial seed: 65 both, 11 client, 0 server (76 jars). - tooling/sync-server-mods.sh mirrors the both/server jars from $DISTRIBUTION_WEB_ROOT into ./server-mods/ (authoritative; prunes strays; halts on a missing jar). Replaces render-pack.sh. - compose: minecraft mounts ./server-mods:/mods:ro with REMOVE_OLD_MODS=TRUE (itzg auto-syncs /mods -> /data/mods). Removed PACKWIZ_URL, the pack. extra_host (auth. kept for authlib), and depends_on caddy (drasl kept). Both classify-mods.py and sync-server-mods.sh resolve their source dir as: CLI arg / MODS_DIST_DIR env / $DISTRIBUTION_WEB_ROOT (in that order). Removed: tooling/render-pack.sh + add-custom-mod.sh (packwiz tooling), pack/ (packwiz source), custom/ (76 jars now sourced from the distribution), the pack. caddy vhost + its mounts/alias, and the packwiz .gitignore block. Client distribution is UNCHANGED: HeliosLauncher still installs the full modset from distribution.json. Docs (CLAUDE.md, plan/04/05/14, runtime) updated; plan/04-packwiz.md stubbed as superseded by plan/04-mods.md. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -3,9 +3,9 @@
|
||||
# ──────────────────────────────────────────────────────────────────
|
||||
# Single, unified compose. One file holds the whole stack:
|
||||
# drasl auth + skins (Yggdrasil), internal only
|
||||
# minecraft the server (itzg/NEOFORGE), installs mods via packwiz
|
||||
# minecraft the server (itzg/NEOFORGE), mods from ./server-mods volume
|
||||
# mc-backup world backups every 6h via RCON
|
||||
# caddy internal ingress — routes auth./pack./apex/launcher/avatar.
|
||||
# caddy internal ingress — routes auth./apex/launcher/avatar.
|
||||
# /distribution. by Host header (conf.d/*.caddy)
|
||||
# nmsr skin/avatar renderer at avatar.${BASE_DOMAIN}
|
||||
# uptime-kuma status monitoring at status.${BASE_DOMAIN}
|
||||
@@ -16,7 +16,7 @@
|
||||
# Production TLS terminates at the HOST's nginx in front of caddy
|
||||
# (nginx/ulicraft-caddy.conf.tmpl + Let's Encrypt); caddy is published on a
|
||||
# localhost-only port (CADDY_HTTP_BIND/CADDY_HTTP_PORT in .env). Containers reach
|
||||
# the stack's own names internally via caddy's mcnet aliases (auth./pack.).
|
||||
# the stack's own names internally via caddy's mcnet alias (auth.).
|
||||
# ──────────────────────────────────────────────────────────────────
|
||||
|
||||
services:
|
||||
@@ -71,8 +71,12 @@ services:
|
||||
ENFORCE_SECURE_PROFILE: "FALSE" # required for authlib-injector on 1.21+
|
||||
ALLOW_FLIGHT: "TRUE" # many tech mods need this
|
||||
|
||||
# ── Mod source: packwiz pack served by caddy (alias pack.) ──
|
||||
PACKWIZ_URL: "http://pack.${BASE_DOMAIN}/pack.toml"
|
||||
# ── Mod source: filtered subset of the distribution modset ──
|
||||
# Jars are synced into ./server-mods by tooling/sync-server-mods.sh
|
||||
# (both/server entries from mods-sides.json) and mounted at /mods below;
|
||||
# itzg auto-syncs /mods → /data/mods. REMOVE_OLD_MODS makes that mirror
|
||||
# authoritative so removed mods get pruned. See plan/04-mods.md.
|
||||
REMOVE_OLD_MODS: "TRUE"
|
||||
|
||||
# ── RCON for remote admin ───────────────────────────────────
|
||||
ENABLE_RCON: "TRUE"
|
||||
@@ -82,16 +86,15 @@ services:
|
||||
TZ: "Europe/Madrid"
|
||||
volumes:
|
||||
- mc_data:/data
|
||||
- ./runtime:/extras:ro # authlib-injector.jar lives here
|
||||
- ./runtime:/extras:ro # authlib-injector.jar lives here
|
||||
- ./server-mods:/mods:ro # itzg auto-syncs /mods → /data/mods
|
||||
depends_on:
|
||||
- drasl
|
||||
- caddy # pack./auth. must resolve at boot
|
||||
- drasl # authlib (auth.) must resolve at boot
|
||||
# Containers don't inherit the host's /etc/hosts; the LAN resolver returns a
|
||||
# dead address for the public names. Pin auth./pack. to the host so HTTPS to
|
||||
# them lands on the host's nginx (valid LE cert) -> caddy -> service.
|
||||
# dead address for the public names. Pin auth. to the host so HTTPS to it
|
||||
# lands on the host's nginx (valid LE cert) -> caddy -> drasl.
|
||||
extra_hosts:
|
||||
- "auth.${BASE_DOMAIN}:host-gateway"
|
||||
- "pack.${BASE_DOMAIN}:host-gateway"
|
||||
networks:
|
||||
- mcnet
|
||||
|
||||
@@ -114,7 +117,7 @@ services:
|
||||
- mcnet
|
||||
|
||||
# Internal ingress. Routes every vhost by Host header (conf.d/*.caddy):
|
||||
# auth. -> drasl, pack. -> packwiz files, apex -> landing + /launcher,
|
||||
# auth. -> drasl, apex -> landing + /launcher,
|
||||
# avatar. -> nmsr, status. -> uptime-kuma, distribution. -> static site.
|
||||
# Published on a localhost-only port; the host's nginx terminates TLS in
|
||||
# front of it (nginx/ulicraft-caddy.conf.tmpl).
|
||||
@@ -135,13 +138,6 @@ services:
|
||||
- ./caddy/conf.d/50-status.caddy:/etc/caddy/conf.d/50-status.caddy:ro
|
||||
- ./www:/srv/www:ro
|
||||
- ./launcher:/srv/launcher:ro
|
||||
- ./pack:/srv/pack:ro
|
||||
# Custom (locally-hosted) mod jars live OUTSIDE ./pack so packwiz refresh
|
||||
# doesn't index them as direct files. Served at pack.${BASE_DOMAIN}/custom/.
|
||||
# Nested under the :ro /srv/pack mount — the mountpoint pack/custom/ must
|
||||
# pre-exist on the host (tracked via pack/custom/.gitkeep) or Docker can't
|
||||
# mkdir it in the read-only parent.
|
||||
- ./custom:/srv/pack/custom:ro
|
||||
# Static site from ANOTHER repo (absolute host path in .env).
|
||||
- ${DISTRIBUTION_WEB_ROOT:?DISTRIBUTION_WEB_ROOT unset in .env}:/srv/distribution:ro
|
||||
networks:
|
||||
@@ -149,7 +145,6 @@ services:
|
||||
# Containers resolve the stack's own public names to caddy internally.
|
||||
aliases:
|
||||
- "auth.${BASE_DOMAIN}"
|
||||
- "pack.${BASE_DOMAIN}"
|
||||
|
||||
# Avatar/skin renderer — built from source (docker/nmsr/Dockerfile), pulls
|
||||
# player profiles from Drasl over mcnet. caddy proxies avatar. -> nmsr:8080.
|
||||
|
||||
Reference in New Issue
Block a user