Caddy phase 2: TLS via Porkbun DNS-01 wildcard certs
- Caddyfile: drop http:// site prefixes, global acme_dns porkbun block, HTTPS redirects on the bare-IP and legacy vhosts - new dankclaw/caddy/Containerfile: xcaddy build with caddy-dns/porkbun - compose: caddy uses franksdank/caddy-porkbun:latest + Porkbun env vars - deploy.sh: build the image on first deploy if missing - .env.example: rename PORKBUN_API_SECRET -> PORKBUN_API_SECRET_KEY (the name the caddy-dns/porkbun module expects) - tests: 7 new caddyfile/compose seams for the TLS config
This commit is contained in:
@@ -35,7 +35,9 @@ SIGNAL_ACCOUNT=+15551234567
|
||||
# Comma-separated E.164 numbers allowed to message the agent.
|
||||
SIGNAL_ALLOWED_USERS=+15551234567
|
||||
|
||||
# Porkbun API (franksdank.cloud zone). Caddy uses these for DNS-01
|
||||
# Let's Encrypt wildcard cert issuance. Scope the token to this zone only.
|
||||
# Porkbun API (franksdank.cloud + franksdank.casa zones). Caddy uses these
|
||||
# for DNS-01 Let's Encrypt wildcard cert issuance. Porkbun API keys are
|
||||
# account-wide; rotate them here rather than in the dashboard.
|
||||
# PORKBUN_API_SECRET_KEY is the name the caddy-dns/porkbun module expects.
|
||||
PORKBUN_API_KEY=changeme
|
||||
PORKBUN_API_SECRET=changeme
|
||||
PORKBUN_API_SECRET_KEY=changeme
|
||||
|
||||
+40
-28
@@ -15,21 +15,33 @@
|
||||
# hash (CADDY_BASICAUTH_HASH from the host .env, git-ignored) into
|
||||
# /home/dank/Containers/caddy/Caddyfile, which the container mounts.
|
||||
#
|
||||
# Phase 1 uses explicit http:// site addresses (no TLS yet). Phase 2 drops
|
||||
# the prefix and adds a wildcard Let's Encrypt cert via DNS-01 (Porkbun).
|
||||
# TLS: real Let's Encrypt certs. Site addresses carry no http:// prefix,
|
||||
# so Caddy serves HTTPS (and auto-redirects HTTP). Certs are wildcard
|
||||
# (dns-01) via the global acme_dns block below, using the Porkbun module
|
||||
# built into the franksdank/caddy-porkbun image (caddy/Containerfile).
|
||||
# That needs no inbound ports and works from the LAN, where dnsmasq
|
||||
# resolves these names to 192.168.0.143.
|
||||
|
||||
{
|
||||
admin off
|
||||
email admin@franksdank.cloud
|
||||
|
||||
# Solve ACME challenges for every site via Porkbun DNS (no port 80/443
|
||||
# reachability needed). Credentials come from the container environment
|
||||
# (compose.yaml, from the host .env — never committed).
|
||||
acme_dns porkbun {
|
||||
api_key {env.PORKBUN_API_KEY}
|
||||
api_secret_key {env.PORKBUN_API_SECRET_KEY}
|
||||
}
|
||||
}
|
||||
|
||||
# --- Bare-IP access (health checks, convenience) ---
|
||||
:80 {
|
||||
redir http://dankclaw.franksdank.cloud/ 302
|
||||
redir https://dankclaw.franksdank.cloud/ 302
|
||||
}
|
||||
|
||||
# --- Homepage (password protected) ---
|
||||
http://dankclaw.franksdank.cloud {
|
||||
dankclaw.franksdank.cloud {
|
||||
basicauth {
|
||||
dank $2a$14$REPLACE_WITH_HASH
|
||||
}
|
||||
@@ -38,8 +50,8 @@ http://dankclaw.franksdank.cloud {
|
||||
}
|
||||
|
||||
# --- Legacy name: the media host has no Caddy of its own anymore ---
|
||||
http://dankserver.franksdank.cloud {
|
||||
redir http://dankclaw.franksdank.cloud/ 302
|
||||
dankserver.franksdank.cloud {
|
||||
redir https://dankclaw.franksdank.cloud/ 302
|
||||
}
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
@@ -47,7 +59,7 @@ http://dankserver.franksdank.cloud {
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
# --- SearXNG (quadlet; behind the Gluetun tunnel, published 8081) ---
|
||||
http://search.franksdank.cloud {
|
||||
search.franksdank.cloud {
|
||||
basicauth {
|
||||
dank $2a$14$REPLACE_WITH_HASH
|
||||
}
|
||||
@@ -55,12 +67,12 @@ http://search.franksdank.cloud {
|
||||
}
|
||||
|
||||
# --- ComfyUI ---
|
||||
http://comfyui.franksdank.cloud {
|
||||
comfyui.franksdank.cloud {
|
||||
reverse_proxy comfyui:8188
|
||||
}
|
||||
|
||||
# --- OpenWebUI (quadlet on slirp4netns; published 3005) ---
|
||||
http://chat.franksdank.cloud {
|
||||
chat.franksdank.cloud {
|
||||
basicauth {
|
||||
dank $2a$14$REPLACE_WITH_HASH
|
||||
}
|
||||
@@ -68,7 +80,7 @@ http://chat.franksdank.cloud {
|
||||
}
|
||||
|
||||
# --- Hermes ---
|
||||
http://hermes.franksdank.cloud {
|
||||
hermes.franksdank.cloud {
|
||||
basicauth {
|
||||
dank $2a$14$REPLACE_WITH_HASH
|
||||
}
|
||||
@@ -76,12 +88,12 @@ http://hermes.franksdank.cloud {
|
||||
}
|
||||
|
||||
# --- Gitea (quadlet; published 3000) ---
|
||||
http://gitea.franksdank.cloud {
|
||||
gitea.franksdank.cloud {
|
||||
reverse_proxy 192.168.0.143:3000
|
||||
}
|
||||
|
||||
# --- Grafana ---
|
||||
http://grafana.franksdank.cloud {
|
||||
grafana.franksdank.cloud {
|
||||
basicauth {
|
||||
dank $2a$14$REPLACE_WITH_HASH
|
||||
}
|
||||
@@ -89,7 +101,7 @@ http://grafana.franksdank.cloud {
|
||||
}
|
||||
|
||||
# --- Prometheus ---
|
||||
http://prometheus.franksdank.cloud {
|
||||
prometheus.franksdank.cloud {
|
||||
basicauth {
|
||||
dank $2a$14$REPLACE_WITH_HASH
|
||||
}
|
||||
@@ -97,7 +109,7 @@ http://prometheus.franksdank.cloud {
|
||||
}
|
||||
|
||||
# --- Loki ---
|
||||
http://loki.franksdank.cloud {
|
||||
loki.franksdank.cloud {
|
||||
reverse_proxy loki:3100
|
||||
}
|
||||
|
||||
@@ -106,21 +118,21 @@ http://loki.franksdank.cloud {
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
# --- Plex (existing, kept) ---
|
||||
http://plex.franksdank.casa {
|
||||
plex.franksdank.casa {
|
||||
reverse_proxy 192.168.0.235:32400
|
||||
}
|
||||
|
||||
http://plex.franksdank.cloud {
|
||||
plex.franksdank.cloud {
|
||||
reverse_proxy 192.168.0.235:32400
|
||||
}
|
||||
|
||||
# --- Calibre-Web ---
|
||||
http://books.franksdank.cloud {
|
||||
books.franksdank.cloud {
|
||||
reverse_proxy 192.168.0.235:8083
|
||||
}
|
||||
|
||||
# --- RomM ---
|
||||
http://romm.franksdank.cloud {
|
||||
romm.franksdank.cloud {
|
||||
basicauth {
|
||||
dank $2a$14$REPLACE_WITH_HASH
|
||||
}
|
||||
@@ -128,7 +140,7 @@ http://romm.franksdank.cloud {
|
||||
}
|
||||
|
||||
# --- Copyparty ---
|
||||
http://files.franksdank.cloud {
|
||||
files.franksdank.cloud {
|
||||
basicauth {
|
||||
dank $2a$14$REPLACE_WITH_HASH
|
||||
}
|
||||
@@ -136,7 +148,7 @@ http://files.franksdank.cloud {
|
||||
}
|
||||
|
||||
# --- Jellyfin ---
|
||||
http://jellyfin.franksdank.cloud {
|
||||
jellyfin.franksdank.cloud {
|
||||
reverse_proxy 192.168.0.235:8096 {
|
||||
transport http {
|
||||
versions h2c 1.1
|
||||
@@ -145,36 +157,36 @@ http://jellyfin.franksdank.cloud {
|
||||
}
|
||||
|
||||
# --- *arr Stack ---
|
||||
http://radarr.franksdank.cloud {
|
||||
radarr.franksdank.cloud {
|
||||
reverse_proxy 192.168.0.235:7878
|
||||
}
|
||||
|
||||
http://sonarr.franksdank.cloud {
|
||||
sonarr.franksdank.cloud {
|
||||
reverse_proxy 192.168.0.235:8989
|
||||
}
|
||||
|
||||
http://lidarr.franksdank.cloud {
|
||||
lidarr.franksdank.cloud {
|
||||
reverse_proxy 192.168.0.235:8686
|
||||
}
|
||||
|
||||
http://readarr.franksdank.cloud {
|
||||
readarr.franksdank.cloud {
|
||||
reverse_proxy 192.168.0.235:8787
|
||||
}
|
||||
|
||||
http://prowlarr.franksdank.cloud {
|
||||
prowlarr.franksdank.cloud {
|
||||
reverse_proxy 192.168.0.235:9696
|
||||
}
|
||||
|
||||
http://qbittorrent.franksdank.cloud {
|
||||
qbittorrent.franksdank.cloud {
|
||||
reverse_proxy 192.168.0.235:8080
|
||||
}
|
||||
|
||||
# --- Optional: Jackett ---
|
||||
# http://jackett.franksdank.cloud {
|
||||
# jackett.franksdank.cloud {
|
||||
# reverse_proxy 192.168.0.235:9117
|
||||
# }
|
||||
|
||||
# --- Optional: Whisparr ---
|
||||
# http://whisparr.franksdank.cloud {
|
||||
# whisparr.franksdank.cloud {
|
||||
# reverse_proxy 192.168.0.235:6969
|
||||
# }
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
# Caddy with the Porkbun DNS provider (github.com/caddy-dns/porkbun).
|
||||
#
|
||||
# The porkbun module lets Caddy solve Let's Encrypt DNS-01 challenges
|
||||
# directly through the Porkbun API, so the wildcard cert for
|
||||
# *.franksdank.cloud / *.franksdank.casa can be issued and renewed without
|
||||
# any port 80/443 reachability from the internet (see the Caddyfile in
|
||||
# ../Caddyfile and docs/Infrastructure/LAN-DNS.md).
|
||||
#
|
||||
# Build on dankclaw (podman rootless, same as every other container here):
|
||||
# podman build -t franksdank/caddy-porkbun:latest -f dankclaw/caddy/Containerfile .
|
||||
#
|
||||
# The first build runs an xcaddy Go compilation and takes a few minutes.
|
||||
# Rebuild only when Caddy or the porkbun module must be updated.
|
||||
|
||||
FROM docker.io/library/caddy:2-builder AS builder
|
||||
|
||||
RUN xcaddy build \
|
||||
--with github.com/caddy-dns/porkbun \
|
||||
--output /usr/bin/caddy-porkbun
|
||||
|
||||
FROM docker.io/library/caddy:2
|
||||
COPY --from=builder /usr/bin/caddy-porkbun /usr/bin/caddy
|
||||
@@ -199,12 +199,18 @@ services:
|
||||
# REPLACE_WITH_HASH placeholder. Certs/config live under
|
||||
# /home/dank/Containers/caddy (rootless-writable).
|
||||
caddy:
|
||||
image: docker.io/library/caddy:latest
|
||||
# Locally built: stock Caddy + the Porkbun DNS provider
|
||||
# (dankclaw/caddy/Containerfile). See that file for build instructions.
|
||||
image: franksdank/caddy-porkbun:latest
|
||||
container_name: caddy
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
environment:
|
||||
# Consumed by the Caddyfile's acme_dns block (DNS-01 wildcard certs).
|
||||
PORKBUN_API_KEY: ${PORKBUN_API_KEY}
|
||||
PORKBUN_API_SECRET_KEY: ${PORKBUN_API_SECRET_KEY}
|
||||
volumes:
|
||||
- /home/dank/Containers/caddy/Caddyfile:/etc/caddy/Caddyfile:ro
|
||||
- /home/dank/Containers/caddy/data:/data
|
||||
|
||||
Reference in New Issue
Block a user