Add NMSR-as-a-Service (NickAcPT/nmsr-rs) rendering players' skins/avatars,
sourced from Drasl instead of Mojang.
- docker/nmsr/Dockerfile build from source, pinned to commit 948ba4bc027b
(ears feature, lavapipe software Vulkan)
- nmsr/config.toml.tmpl [mojank] -> http://auth.${BASE_DOMAIN}; Drasl
serves the Mojang-compatible routes at its bare
BaseURL and embeds absolute skin URLs that NMSR
fetches directly. allow_offline_mode_uuids=true.
- docker-compose.nmsr.yml nmsr service (build), host bind 127.0.0.1:9898
only, config mount; mounts the caddy avatar snippet
- caddy/conf.d/40-avatar.caddy avatar.${BASE_DOMAIN} -> reverse_proxy nmsr:8080
- nginx-front + LE_SUBDOMAINS public TLS vhost (HSTS) + cert for avatar
- render-config.sh / .gitignore render + ignore nmsr/config.toml
Skin resolution stays internal over mcnet (caddy alias -> drasl), no public
round-trip.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
148 lines
5.9 KiB
Cheetah
148 lines
5.9 KiB
Cheetah
# ──────────────────────────────────────────────────────────────────
|
|
# Ulicraft host nginx — TLS terminator in FRONT of caddy.
|
|
# ──────────────────────────────────────────────────────────────────
|
|
# Alternative to ulicraft.conf.tmpl. Instead of nginx serving the static
|
|
# files + proxying only drasl, here caddy (the docker container) is the single
|
|
# ingress for ALL vhosts and nginx just terminates TLS and reverse-proxies
|
|
# everything to caddy by Host header.
|
|
#
|
|
# Caddy must be published on a localhost port — set in .env:
|
|
# CADDY_HTTP_PORT=8880
|
|
# CADDY_HTTP_BIND=127.0.0.1
|
|
# and the stack brought up with the caddy override (NOT the nginx override):
|
|
# docker compose -f docker-compose.yml -f docker-compose.caddy.yml \
|
|
# -f docker-compose.static.yml up -d
|
|
#
|
|
# Render with BOTH vars then install:
|
|
# CADDY_HTTP_PORT=8880 BASE_DOMAIN=ulicraft.net APP_DIR=/home/ubuntu/mc/ulicraft-server-v1 \
|
|
# envsubst '$CADDY_HTTP_PORT $BASE_DOMAIN $APP_DIR' \
|
|
# < nginx/ulicraft-caddy.conf.tmpl | sudo tee /etc/nginx/sites-available/ulicraft.conf
|
|
# sudo ln -sf /etc/nginx/sites-available/ulicraft.conf /etc/nginx/sites-enabled/
|
|
# sudo nginx -t && sudo systemctl reload nginx
|
|
#
|
|
# Prereqs:
|
|
# - certs issued: tooling/issue-letsencrypt.sh -> $APP_DIR/certs/<name>/{cert,key}.pem
|
|
# ──────────────────────────────────────────────────────────────────
|
|
|
|
upstream ulicraft_caddy {
|
|
server 127.0.0.1:${CADDY_HTTP_PORT};
|
|
}
|
|
|
|
# HTTP -> HTTPS for every name.
|
|
server {
|
|
listen 80;
|
|
listen [::]:80;
|
|
server_name ${BASE_DOMAIN} www.${BASE_DOMAIN} auth.${BASE_DOMAIN} pack.${BASE_DOMAIN} distribution.${BASE_DOMAIN} avatar.${BASE_DOMAIN};
|
|
return 301 https://$host$request_uri;
|
|
}
|
|
|
|
# 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,
|
|
# pack -> packwiz files).
|
|
server {
|
|
listen 443 ssl http2;
|
|
listen [::]:443 ssl http2;
|
|
server_name ${BASE_DOMAIN};
|
|
|
|
ssl_certificate ${APP_DIR}/certs/${BASE_DOMAIN}/cert.pem;
|
|
ssl_certificate_key ${APP_DIR}/certs/${BASE_DOMAIN}/key.pem;
|
|
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
|
|
|
|
client_max_body_size 4m; # skin uploads (auth) reuse the same proxy block
|
|
|
|
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;
|
|
}
|
|
}
|
|
|
|
# www -> apex canonical redirect (needs its own cert; covered by LE_SUBDOMAINS).
|
|
server {
|
|
listen 443 ssl http2;
|
|
listen [::]:443 ssl http2;
|
|
server_name www.${BASE_DOMAIN};
|
|
|
|
ssl_certificate ${APP_DIR}/certs/www.${BASE_DOMAIN}/cert.pem;
|
|
ssl_certificate_key ${APP_DIR}/certs/www.${BASE_DOMAIN}/key.pem;
|
|
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
|
|
|
|
return 301 https://${BASE_DOMAIN}$request_uri;
|
|
}
|
|
|
|
server {
|
|
listen 443 ssl http2;
|
|
listen [::]:443 ssl http2;
|
|
server_name auth.${BASE_DOMAIN};
|
|
|
|
ssl_certificate ${APP_DIR}/certs/auth.${BASE_DOMAIN}/cert.pem;
|
|
ssl_certificate_key ${APP_DIR}/certs/auth.${BASE_DOMAIN}/key.pem;
|
|
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
|
|
|
|
client_max_body_size 4m; # skin uploads
|
|
|
|
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 {
|
|
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 {
|
|
listen 443 ssl http2;
|
|
listen [::]:443 ssl http2;
|
|
server_name distribution.${BASE_DOMAIN};
|
|
|
|
ssl_certificate ${APP_DIR}/certs/distribution.${BASE_DOMAIN}/cert.pem;
|
|
ssl_certificate_key ${APP_DIR}/certs/distribution.${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 {
|
|
listen 443 ssl http2;
|
|
listen [::]:443 ssl http2;
|
|
server_name avatar.${BASE_DOMAIN};
|
|
|
|
ssl_certificate ${APP_DIR}/certs/avatar.${BASE_DOMAIN}/cert.pem;
|
|
ssl_certificate_key ${APP_DIR}/certs/avatar.${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;
|
|
}
|
|
}
|