feat(ingress): public distribution.${BASE_DOMAIN} static vhost
Serve a static site at distribution.${BASE_DOMAIN} whose web root lives in
another repo (DISTRIBUTION_WEB_ROOT, bind-mounted read-only into caddy):
- caddy/conf.d/30-distribution.caddy file_server vhost
- docker-compose.distribution.yml mount snippet + external web root
- issue-letsencrypt.sh / .env.example add distribution to LE_SUBDOMAINS
- ulicraft-caddy.conf.tmpl TLS-front block proxying to caddy
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
11
.env.example
11
.env.example
@@ -23,8 +23,13 @@ RCON_PASSWORD=change-me-to-something-random
|
|||||||
# CADDY_HTTP_PORT=8880
|
# CADDY_HTTP_PORT=8880
|
||||||
# CADDY_HTTP_BIND=127.0.0.1
|
# CADDY_HTTP_BIND=127.0.0.1
|
||||||
# Then render nginx/ulicraft-caddy.conf.tmpl with CADDY_HTTP_PORT.
|
# Then render nginx/ulicraft-caddy.conf.tmpl with CADDY_HTTP_PORT.
|
||||||
# CADDY_HTTP_PORT=80
|
CADDY_HTTP_PORT=80
|
||||||
# CADDY_HTTP_BIND=0.0.0.0
|
CADDY_HTTP_BIND=0.0.0.0
|
||||||
|
|
||||||
|
# distribution.${BASE_DOMAIN} static vhost (docker-compose.distribution.yml).
|
||||||
|
# Absolute host path to the built static site — it lives in ANOTHER repo.
|
||||||
|
# Bind-mounted read-only into caddy and served at distribution.${BASE_DOMAIN}.
|
||||||
|
DISTRIBUTION_WEB_ROOT=/home/oier/projects/mc-mods/ulicraft-group/ulicraft-distribution/dist
|
||||||
# Only needed if using CurseForge-exclusive mods:
|
# Only needed if using CurseForge-exclusive mods:
|
||||||
# CF_API_KEY=your-curseforge-api-key
|
# CF_API_KEY=your-curseforge-api-key
|
||||||
|
|
||||||
@@ -32,7 +37,7 @@ RCON_PASSWORD=change-me-to-something-random
|
|||||||
# 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
|
LE_SUBDOMAINS=auth pack distribution
|
||||||
# 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
|
||||||
|
|||||||
8
caddy/conf.d/30-distribution.caddy
Normal file
8
caddy/conf.d/30-distribution.caddy
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# Distribution toggle — static site served from a web root in ANOTHER repo.
|
||||||
|
# The host path is set by DISTRIBUTION_WEB_ROOT in .env and bind-mounted to
|
||||||
|
# /srv/distribution by docker-compose.caddy.yml. Mounted only when that var is
|
||||||
|
# set (see the distribution override).
|
||||||
|
http://distribution.{$BASE_DOMAIN} {
|
||||||
|
root * /srv/distribution
|
||||||
|
file_server browse
|
||||||
|
}
|
||||||
15
docker-compose.distribution.yml
Normal file
15
docker-compose.distribution.yml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
# ──────────────────────────────────────────────────────────────────
|
||||||
|
# Distribution vhost — distribution.${BASE_DOMAIN}, static files from a web
|
||||||
|
# root that lives in ANOTHER repo. Layered on top of the caddy ingress.
|
||||||
|
# ──────────────────────────────────────────────────────────────────
|
||||||
|
# docker compose -f docker-compose.yml -f docker-compose.caddy.yml \
|
||||||
|
# -f docker-compose.distribution.yml up -d
|
||||||
|
#
|
||||||
|
# DISTRIBUTION_WEB_ROOT (.env) = absolute host path to the built static site in
|
||||||
|
# the other repo. Bind-mounted read-only; caddy serves it via the
|
||||||
|
# conf.d/30-distribution.caddy snippet.
|
||||||
|
services:
|
||||||
|
caddy:
|
||||||
|
volumes:
|
||||||
|
- ./caddy/conf.d/30-distribution.caddy:/etc/caddy/conf.d/30-distribution.caddy:ro
|
||||||
|
- ${DISTRIBUTION_WEB_ROOT:?DISTRIBUTION_WEB_ROOT unset in .env}:/srv/distribution:ro
|
||||||
@@ -32,7 +32,7 @@ upstream ulicraft_caddy {
|
|||||||
server {
|
server {
|
||||||
listen 80;
|
listen 80;
|
||||||
listen [::]:80;
|
listen [::]:80;
|
||||||
server_name ${BASE_DOMAIN} auth.${BASE_DOMAIN} pack.${BASE_DOMAIN};
|
server_name ${BASE_DOMAIN} auth.${BASE_DOMAIN} pack.${BASE_DOMAIN} distribution.${BASE_DOMAIN};
|
||||||
return 301 https://$host$request_uri;
|
return 301 https://$host$request_uri;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,3 +96,21 @@ server {
|
|||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
listen [::]:443 ssl;
|
||||||
|
http2 on;
|
||||||
|
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;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
# OVH_CK OVH consumer key (obtained on first run — see below)
|
# OVH_CK OVH consumer key (obtained on first run — see below)
|
||||||
# OVH_END_POINT OVH API endpoint (e.g. ovh-eu)
|
# OVH_END_POINT OVH API endpoint (e.g. ovh-eu)
|
||||||
# optional:
|
# optional:
|
||||||
# LE_SUBDOMAINS space-separated (default: "auth pack")
|
# LE_SUBDOMAINS space-separated (default: "auth pack distribution")
|
||||||
# LE_STAGING=1 use the LE staging CA (untrusted, for dry runs)
|
# LE_STAGING=1 use the LE staging CA (untrusted, for dry runs)
|
||||||
#
|
#
|
||||||
# First-time OVH consumer key: set OVH_AK/OVH_AS/OVH_END_POINT, leave OVH_CK
|
# First-time OVH consumer key: set OVH_AK/OVH_AS/OVH_END_POINT, leave OVH_CK
|
||||||
@@ -53,7 +53,7 @@ ACME="${ACME_SH:-$HOME/.acme.sh/acme.sh}"
|
|||||||
then re-run (or set ACME_SH=/path/to/acme.sh)."
|
then re-run (or set ACME_SH=/path/to/acme.sh)."
|
||||||
|
|
||||||
CERT_DIR="${CERT_DIR:-certs}"
|
CERT_DIR="${CERT_DIR:-certs}"
|
||||||
read -r -a SUBDOMAINS <<< "${LE_SUBDOMAINS:-auth pack}"
|
read -r -a SUBDOMAINS <<< "${LE_SUBDOMAINS:-auth pack distribution}"
|
||||||
|
|
||||||
if [ "${LE_STAGING:-0}" = "1" ]; then
|
if [ "${LE_STAGING:-0}" = "1" ]; then
|
||||||
SERVER="letsencrypt_test"; warn "STAGING mode — certs will NOT be trusted by browsers"
|
SERVER="letsencrypt_test"; warn "STAGING mode — certs will NOT be trusted by browsers"
|
||||||
|
|||||||
Reference in New Issue
Block a user