refactor(ingress): extract caddy to its own compose file; add nginx path
Caddy is no longer in the base stack. Two ingress paths now: - docker-compose.caddy.yml — LAN/air-gap; build-stack.sh adds it for all up modes + the prep pre-bake. Holds the mcnet auth./pack. aliases. - docker-compose.nginx.yml — production behind the host's nginx: publishes drasl on 127.0.0.1:25585, points minecraft at the host (extra_hosts) over HTTPS for pack + authlib. Base loses the caddy service and minecraft's caddy depends_on (re-added by caddy.yml). Blessing Skin override now requires caddy.yml (it only swaps caddy's core conf). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,9 +1,11 @@
|
||||
# ──────────────────────────────────────────────────────────────────
|
||||
# Blessing Skin auth variant — use INSTEAD of Drasl.
|
||||
# ──────────────────────────────────────────────────────────────────
|
||||
# Layer this over the base file:
|
||||
# Layer this over the base file AND the caddy ingress (caddy lives in its own
|
||||
# file now; this override only swaps caddy's core conf, so caddy.yml is required):
|
||||
#
|
||||
# docker compose -f docker-compose.yml -f docker-compose.blessingskin.yml up -d
|
||||
# docker compose -f docker-compose.yml -f docker-compose.caddy.yml \
|
||||
# -f docker-compose.blessingskin.yml up -d
|
||||
#
|
||||
# What it does vs the base stack:
|
||||
# - drasl → left running but UNUSED + unreachable (Caddy no longer
|
||||
|
||||
46
docker-compose.caddy.yml
Normal file
46
docker-compose.caddy.yml
Normal file
@@ -0,0 +1,46 @@
|
||||
# ──────────────────────────────────────────────────────────────────
|
||||
# Caddy ingress — LAN / air-gap path. NOT started with the base stack.
|
||||
# ──────────────────────────────────────────────────────────────────
|
||||
# Caddy was moved out of docker-compose.yml so the base stack can run behind
|
||||
# the host's nginx (production) without it. build-stack.sh adds this file for
|
||||
# its online/airgap/core modes; static/mirror overrides mount extra vhosts in.
|
||||
#
|
||||
# docker compose -f docker-compose.yml -f docker-compose.caddy.yml up -d
|
||||
#
|
||||
# Holds the mcnet aliases (auth./pack.${BASE_DOMAIN}) so containers resolve the
|
||||
# stack's own names internally — this is why minecraft can reach the pack here
|
||||
# without extra_hosts (the nginx path uses extra_hosts instead).
|
||||
services:
|
||||
caddy:
|
||||
image: caddy:alpine
|
||||
container_name: caddy
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "80:80"
|
||||
environment:
|
||||
BASE_DOMAIN: ${BASE_DOMAIN}
|
||||
volumes:
|
||||
- ./caddy/Caddyfile:/etc/caddy/Caddyfile:ro
|
||||
- ./caddy/conf.d/00-core.caddy:/etc/caddy/conf.d/00-core.caddy:ro
|
||||
- ./caddy/conf.d/10-static.caddy:/etc/caddy/conf.d/10-static.caddy:ro
|
||||
- ./www:/srv/www:ro
|
||||
- ./mirror/launcher:/srv/launcher:ro
|
||||
- ./caddy/caddy-root-ca.crt:/srv/ca-pub/ca.crt: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/.
|
||||
- ./custom:/srv/pack/custom:ro
|
||||
networks:
|
||||
mcnet:
|
||||
# The upstream spoof-host aliases live in docker-compose.mirror.yml —
|
||||
# adding them here would hijack maven.neoforged.net etc. for ALL mcnet
|
||||
# containers, breaking the ONLINE NeoForge install during pre-bake.
|
||||
aliases:
|
||||
- "auth.${BASE_DOMAIN}"
|
||||
- "pack.${BASE_DOMAIN}"
|
||||
|
||||
# Restore the ordering the base file used to have (base drops it so it can run
|
||||
# caddy-less behind nginx).
|
||||
minecraft:
|
||||
depends_on:
|
||||
- caddy
|
||||
30
docker-compose.nginx.yml
Normal file
30
docker-compose.nginx.yml
Normal file
@@ -0,0 +1,30 @@
|
||||
# ──────────────────────────────────────────────────────────────────
|
||||
# Production ingress = the HOST's nginx + Let's Encrypt. No caddy.
|
||||
# ──────────────────────────────────────────────────────────────────
|
||||
# docker compose -f docker-compose.yml -f docker-compose.nginx.yml up -d
|
||||
#
|
||||
# nginx (on the host, already installed) terminates TLS with the LE certs from
|
||||
# tooling/issue-letsencrypt.sh and:
|
||||
# - serves apex + pack.${BASE_DOMAIN} as static files (./www, ./pack, ./custom)
|
||||
# - reverse-proxies auth.${BASE_DOMAIN} -> 127.0.0.1:25585 (drasl)
|
||||
# See nginx/ulicraft.conf.tmpl.
|
||||
#
|
||||
# This override:
|
||||
# - publishes drasl on localhost so the host nginx can reach it
|
||||
# - points the minecraft container at the host (extra_hosts) over HTTPS, so it
|
||||
# fetches the pack and validates sessions through the same public names the
|
||||
# LE certs cover (JVM trusts Let's Encrypt out of the box)
|
||||
services:
|
||||
drasl:
|
||||
ports:
|
||||
- "127.0.0.1:25585:25585"
|
||||
|
||||
minecraft:
|
||||
# Make the public names resolve to the host running nginx.
|
||||
extra_hosts:
|
||||
- "auth.${BASE_DOMAIN}:host-gateway"
|
||||
- "pack.${BASE_DOMAIN}:host-gateway"
|
||||
environment:
|
||||
# Use HTTPS now that nginx terminates TLS with a publicly-trusted cert.
|
||||
JVM_OPTS: "-javaagent:/extras/authlib-injector.jar=https://auth.${BASE_DOMAIN}/authlib-injector"
|
||||
PACKWIZ_URL: "https://pack.${BASE_DOMAIN}/pack.toml"
|
||||
@@ -5,45 +5,21 @@
|
||||
# DNS is provided by YOUR party DNS server — see tooling/dns-records.sh for the
|
||||
# records to add (online vs airgap). A turnkey dnsmasq is available as an
|
||||
# optional layer: docker-compose.dnsmasq.yml.
|
||||
# - caddy is the only HTTP ingress; holds mcnet aliases so the stack
|
||||
# resolves auth.${BASE_DOMAIN} / packwiz.${BASE_DOMAIN} internally too
|
||||
# - ingress is layered on, NOT in this base file: caddy (docker-compose.caddy.yml,
|
||||
# LAN/air-gap, holds mcnet aliases) OR the host's nginx (docker-compose.nginx.yml
|
||||
# + Let's Encrypt, production)
|
||||
# - drasl handles auth (password login; NO Keycloak/OIDC in this stack)
|
||||
# - packwiz pack is served by caddy at packwiz.${BASE_DOMAIN}
|
||||
# - packwiz pack is served by the ingress at pack.${BASE_DOMAIN}
|
||||
# - minecraft installs mods via PACKWIZ_URL, authlib-injector -> auth.
|
||||
# ──────────────────────────────────────────────────────────────────
|
||||
|
||||
services:
|
||||
# Core ingress. Static site + air-gap mirror are layered in via override
|
||||
# files (docker-compose.static.yml / .mirror.yml) — see build-stack.sh --up.
|
||||
caddy:
|
||||
image: caddy:alpine
|
||||
container_name: caddy
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "80:80"
|
||||
environment:
|
||||
BASE_DOMAIN: ${BASE_DOMAIN}
|
||||
volumes:
|
||||
- ./caddy/Caddyfile:/etc/caddy/Caddyfile:ro
|
||||
- ./caddy/conf.d/00-core.caddy:/etc/caddy/conf.d/00-core.caddy:ro
|
||||
- ./caddy/conf.d/10-static.caddy:/etc/caddy/conf.d/10-static.caddy:ro
|
||||
- ./www:/srv/www:ro
|
||||
- ./mirror/launcher:/srv/launcher:ro
|
||||
- ./caddy/caddy-root-ca.crt:/srv/ca-pub/ca.crt:ro
|
||||
- ./pack:/srv/pack:ro
|
||||
# Custom (locally-hosted) mod jars live OUTSIDE ./pack so packwiz refresh
|
||||
# doesn't index them as direct files — they're external download targets
|
||||
# referenced by pack/mods/*.pw.toml. Served at pack.${BASE_DOMAIN}/custom/.
|
||||
- ./custom:/srv/pack/custom:ro
|
||||
networks:
|
||||
mcnet:
|
||||
# Only the stack's own subdomains in the base. The upstream spoof-host
|
||||
# aliases live in docker-compose.mirror.yml — adding them here would
|
||||
# hijack maven.neoforged.net / libraries.minecraft.net for ALL mcnet
|
||||
# containers, breaking the ONLINE NeoForge install during pre-bake.
|
||||
aliases:
|
||||
- "auth.${BASE_DOMAIN}"
|
||||
- "pack.${BASE_DOMAIN}"
|
||||
# NOTE: the HTTP(S) ingress is NOT in this base file.
|
||||
# - LAN / air-gap: caddy (docker-compose.caddy.yml) — added by build-stack.sh
|
||||
# - production: the HOST's nginx + Let's Encrypt (docker-compose.nginx.yml
|
||||
# publishes drasl to localhost; nginx/ulicraft.conf.tmpl)
|
||||
# Base alone (drasl + minecraft + mc-backup) is not a complete deployment —
|
||||
# always layer one ingress file on top.
|
||||
drasl:
|
||||
image: unmojang/drasl:latest
|
||||
container_name: drasl
|
||||
@@ -95,7 +71,9 @@ 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 ────────────────
|
||||
# ── Mod source: packwiz pack served by the ingress ──────────
|
||||
# http + caddy alias by default; the nginx override switches this to
|
||||
# https + host-gateway (extra_hosts) for the production path.
|
||||
PACKWIZ_URL: "http://pack.${BASE_DOMAIN}/pack.toml"
|
||||
|
||||
# ── RCON for remote admin ───────────────────────────────────
|
||||
@@ -108,8 +86,7 @@ services:
|
||||
- mc_data:/data
|
||||
- ./runtime:/extras:ro # authlib-injector.jar lives here
|
||||
depends_on:
|
||||
- drasl
|
||||
- caddy # packwiz pack is served by caddy
|
||||
- drasl # ingress (caddy/nginx) is layered separately
|
||||
networks:
|
||||
- mcnet
|
||||
|
||||
|
||||
@@ -91,7 +91,8 @@ prep() {
|
||||
log "pre-bake server volume (TYPE=NEOFORGE install, one-shot, online)"
|
||||
# Bring minecraft up once so itzg installs NeoForge + mods into the volume,
|
||||
# then stop it. The party then runs offline against the baked volume.
|
||||
"${COMPOSE[@]}" up -d minecraft
|
||||
# caddy.yml so the pack (pack.${BASE_DOMAIN}) resolves + is served during bake.
|
||||
"${COMPOSE[@]}" -f docker-compose.yml -f docker-compose.caddy.yml up -d minecraft
|
||||
warn "watch logs until 'Done' then re-run with --up; or automate a readiness probe"
|
||||
}
|
||||
|
||||
@@ -102,7 +103,10 @@ prep() {
|
||||
# core base only (no landing, no mirror) — debugging
|
||||
up() {
|
||||
local mode="${1:-airgap}"
|
||||
local -a files=(-f docker-compose.yml)
|
||||
# build-stack is the caddy (LAN/air-gap) deployer; caddy lives in its own file
|
||||
# now (the base stack can also run behind the host's nginx — see
|
||||
# docker-compose.nginx.yml). Always include caddy here.
|
||||
local -a files=(-f docker-compose.yml -f docker-compose.caddy.yml)
|
||||
case "$mode" in
|
||||
core) ;;
|
||||
online) files+=(-f docker-compose.static.yml) ;;
|
||||
|
||||
Reference in New Issue
Block a user