- 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
98 lines
3.5 KiB
Bash
98 lines
3.5 KiB
Bash
#!/usr/bin/env bats
|
|
# Seam: Caddyfile validity.
|
|
#
|
|
# There is exactly one Caddy in the homelab: the container on dankclaw
|
|
# (dankclaw/compose.yaml, service 'caddy'). It fronts every service on both
|
|
# hosts — local services by container name, dankserver services by published
|
|
# LAN port. Site blocks use the flat franksdank.cloud / franksdank.casa
|
|
# convention. The basicauth hash is a placeholder in git; deploy.sh renders
|
|
# the real hash from the host .env (CADDY_BASICAUTH_HASH).
|
|
|
|
load helpers
|
|
|
|
CADDYFILE="$REPO_ROOT/dankclaw/Caddyfile"
|
|
|
|
@test "the Caddyfile lives on dankclaw only (Caddy is consolidated there)" {
|
|
[ -f "$CADDYFILE" ]
|
|
[ ! -f "$REPO_ROOT/dankserver/Caddyfile" ]
|
|
}
|
|
|
|
@test "the Caddyfile uses the flat franksdank.cloud hostname convention" {
|
|
grep -qE '\.franksdank\.cloud' "$CADDYFILE"
|
|
}
|
|
|
|
@test "no .local vhost names remain in the Caddyfile" {
|
|
! grep -qE '^([a-z0-9.-]+\.)?(dankserver|dankclaw)\.local[[:space:]]*\{' \
|
|
"$CADDYFILE"
|
|
}
|
|
|
|
@test "the Caddyfile has balanced braces" {
|
|
local open close
|
|
open=$(grep -o '{' "$CADDYFILE" | wc -l)
|
|
close=$(grep -o '}' "$CADDYFILE" | wc -l)
|
|
[ "$open" -eq "$close" ] || { echo "unbalanced braces ($open vs $close)"; return 1; }
|
|
}
|
|
|
|
@test "caddy validate passes when caddy is available" {
|
|
if command -v caddy >/dev/null 2>&1; then
|
|
caddy validate --config "$CADDYFILE" --adapter caddyfile
|
|
else
|
|
skip "caddy binary not installed locally"
|
|
fi
|
|
}
|
|
|
|
@test "homepage basic auth exists in the Caddyfile" {
|
|
grep -qiE 'basicauth|basic_auth' "$CADDYFILE"
|
|
}
|
|
|
|
@test "the Caddyfile carries the renderable basicauth placeholder" {
|
|
grep -q 'REPLACE_WITH_HASH' "$CADDYFILE"
|
|
}
|
|
|
|
@test "compose no longer defines the quadlet-replaced services" {
|
|
# gitea, its postgres, and open-webui run as boot-persistent quadlets on
|
|
# dankclaw (see dankclaw/gitea/quadlet, dankclaw/open-webui/quadlet).
|
|
! grep -qE '^\s+(gitea|postgres|openwebui):\s*$' "$REPO_ROOT/dankclaw/compose.yaml"
|
|
}
|
|
|
|
@test "the caddy service healthcheck probes the bare-IP catch-all" {
|
|
grep -q 'curl.*-sf.*http://localhost:80/' "$REPO_ROOT/dankclaw/compose.yaml"
|
|
}
|
|
|
|
# --- Phase 2: real TLS via DNS-01 (Porkbun wildcard cert) ---
|
|
|
|
@test "all vhosts use TLS (no http:// site prefix remains)" {
|
|
! grep -qE '^http://' "$CADDYFILE"
|
|
}
|
|
|
|
@test "the Caddyfile configures the Porkbun DNS-01 provider globally" {
|
|
grep -q 'acme_dns porkbun' "$CADDYFILE"
|
|
grep -q '{env.PORKBUN_API_KEY}' "$CADDYFILE"
|
|
grep -q '{env.PORKBUN_API_SECRET_KEY}' "$CADDYFILE"
|
|
}
|
|
|
|
@test "the bare-IP catch-all redirects to the HTTPS homepage" {
|
|
grep -q 'redir https://dankclaw.franksdank.cloud/' "$CADDYFILE"
|
|
}
|
|
|
|
@test "the caddy service uses the locally built porkbun image" {
|
|
grep -q 'franksdank/caddy-porkbun' "$REPO_ROOT/dankclaw/compose.yaml"
|
|
}
|
|
|
|
@test "the caddy service passes the Porkbun credentials from .env" {
|
|
grep -q 'PORKBUN_API_KEY: \${PORKBUN_API_KEY}' "$REPO_ROOT/dankclaw/compose.yaml"
|
|
grep -q 'PORKBUN_API_SECRET_KEY: \${PORKBUN_API_SECRET_KEY}' "$REPO_ROOT/dankclaw/compose.yaml"
|
|
}
|
|
|
|
@test ".env.example carries the Porkbun secret under the module's name" {
|
|
grep -q 'PORKBUN_API_SECRET_KEY=' "$REPO_ROOT/dankclaw/.env.example"
|
|
! grep -q '^PORKBUN_API_SECRET=' "$REPO_ROOT/dankclaw/.env.example"
|
|
}
|
|
|
|
@test "the porkbun caddy image build lives in the repo" {
|
|
local cf="$REPO_ROOT/dankclaw/caddy/Containerfile"
|
|
[ -f "$cf" ] || { echo "missing $cf"; return 1; }
|
|
grep -q 'xcaddy build' "$cf"
|
|
grep -q 'github.com/caddy-dns/porkbun' "$cf"
|
|
}
|