fix: wire CADDY_DOMAIN into Caddyfile template for wildcard cert

CADDY_DOMAIN was required/validated/prompted but never used — the
Caddyfile only referenced GITEA_DOMAIN, producing a single-domain
cert. Now the template uses *.CADDY_DOMAIN as the site address
(wildcard cert) with a host matcher routing GITEA_DOMAIN to Gitea.
This means the cert covers all subdomains under the base domain.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
S
2026-03-01 12:18:53 -05:00
parent 61b46eb876
commit 01f11df417
3 changed files with 14 additions and 5 deletions

View File

@@ -121,7 +121,7 @@ GITHUB_MIRROR_INTERVAL=8h # How often Gitea pushes to GitHub (offsite ba
# TLS / REVERSE PROXY (Caddy — dedicated container per host) # TLS / REVERSE PROXY (Caddy — dedicated container per host)
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
TLS_MODE=cloudflare # TLS mode: "cloudflare" (DNS-01 via CF API) or "existing" (manual certs) TLS_MODE=cloudflare # TLS mode: "cloudflare" (DNS-01 via CF API) or "existing" (manual certs)
CADDY_DOMAIN= # Wildcard base domain (e.g. privacyindesign.com) CADDY_DOMAIN= # Wildcard cert base domain (e.g. privacyindesign.com → cert for *.privacyindesign.com)
CADDY_DATA_PATH= # Absolute path on host for Caddy data (e.g. /mnt/nvme/caddy) CADDY_DATA_PATH= # Absolute path on host for Caddy data (e.g. /mnt/nvme/caddy)
CLOUDFLARE_API_TOKEN= # Cloudflare API token with Zone:DNS:Edit (only if TLS_MODE=cloudflare) CLOUDFLARE_API_TOKEN= # Cloudflare API token with Zone:DNS:Edit (only if TLS_MODE=cloudflare)
SSL_CERT_PATH= # Absolute path to SSL cert (only if TLS_MODE=existing) SSL_CERT_PATH= # Absolute path to SSL cert (only if TLS_MODE=existing)

View File

@@ -145,7 +145,7 @@ if ssh_exec UNRAID "test -f '${CADDY_DATA_PATH}/Caddyfile'" 2>/dev/null; then
else else
TMPFILE=$(mktemp) TMPFILE=$(mktemp)
GITEA_CONTAINER_IP="${UNRAID_GITEA_IP}" GITEA_CONTAINER_IP="${UNRAID_GITEA_IP}"
export GITEA_CONTAINER_IP GITEA_DOMAIN export GITEA_CONTAINER_IP GITEA_DOMAIN CADDY_DOMAIN
# Build TLS block based on TLS_MODE # Build TLS block based on TLS_MODE
if [[ "$TLS_MODE" == "cloudflare" ]]; then if [[ "$TLS_MODE" == "cloudflare" ]]; then
@@ -158,7 +158,7 @@ else
export TLS_BLOCK export TLS_BLOCK
render_template "${SCRIPT_DIR}/templates/Caddyfile.tpl" "$TMPFILE" \ render_template "${SCRIPT_DIR}/templates/Caddyfile.tpl" "$TMPFILE" \
"\${GITEA_DOMAIN} \${TLS_BLOCK} \${GITEA_CONTAINER_IP}" "\${CADDY_DOMAIN} \${GITEA_DOMAIN} \${TLS_BLOCK} \${GITEA_CONTAINER_IP}"
scp_to UNRAID "$TMPFILE" "${CADDY_DATA_PATH}/Caddyfile" scp_to UNRAID "$TMPFILE" "${CADDY_DATA_PATH}/Caddyfile"
rm -f "$TMPFILE" rm -f "$TMPFILE"
log_success "Caddyfile deployed" log_success "Caddyfile deployed"

View File

@@ -2,8 +2,17 @@
# TLS_BLOCK is replaced by the phase script based on TLS_MODE: # TLS_BLOCK is replaced by the phase script based on TLS_MODE:
# cloudflare → dns cloudflare {env.CF_API_TOKEN} # cloudflare → dns cloudflare {env.CF_API_TOKEN}
# existing → tls /path/to/cert /path/to/key # existing → tls /path/to/cert /path/to/key
# Wildcard cert covers *.CADDY_DOMAIN; @gitea routes GITEA_DOMAIN to Gitea.
${GITEA_DOMAIN} { *.${CADDY_DOMAIN} {
${TLS_BLOCK} ${TLS_BLOCK}
@gitea host ${GITEA_DOMAIN}
handle @gitea {
reverse_proxy ${GITEA_CONTAINER_IP}:3000 reverse_proxy ${GITEA_CONTAINER_IP}:3000
} }
handle {
respond "Service not configured" 404
}
}