Replaces the self-signed dev cert flow with a real LE prod cert for dns.l.supported.systems, issued and auto-renewed by a Caddy sidecar using DNS-01 challenge against the Vultr API. Components: - caddy/Dockerfile builds Caddy 2.10.0 with caddy-dns/vultr plugin via xcaddy. GOTOOLCHAIN=auto so xcaddy can fetch newer Go on demand when plugin versions advance their minimum Go. - caddy/Caddyfile uses DNS-01 with explicit public resolvers (1.1.1.1, 9.9.9.9) for the propagation check. Without that, Docker's embedded DNS leaks the container into the host's split-horizon LAN DNS, which returns LAN IPs for ns1.vultr.com and the propagation check fails. - docker-compose: caddy service shares ./caddy-data with coredns via a read-only subpath mount that excludes /acme (account private key). - Healthcheck doubles as a symlinker: maintains stable cert.pem / key.pem names at /data/caddy/ and chmods cert files + their dirs to be readable by CoreDNS's nonroot user. Flips to "healthy" only once the symlinks dereference (i.e. cert exists), gating CoreDNS start via depends_on: service_healthy. - Corefile unchanged — same /etc/coredns/certs/cert.pem path; only the bind-mount source switches from ./certs to ./caddy-data/caddy. - New Makefile target: tls-up orchestrates the bring-up sequence. Cert is valid until Aug 12 2026. Verified end-to-end: dig @127.0.0.1 -p 8853 +tls +tls-hostname=dns.l.supported.systems ... dig @127.0.0.1 -p 8443 +https +tls-hostname=dns.l.supported.systems ...
41 lines
1.8 KiB
Caddyfile
41 lines
1.8 KiB
Caddyfile
# Caddy is used here purely as an ACME client + cert renewer for CoreDNS.
|
|
# The HTTPS site is technically served (Caddy can't issue without a site
|
|
# block), but we don't expose port 443 from this container — only the
|
|
# cert files in /data/caddy/ are consumed by the CoreDNS sidecar.
|
|
{
|
|
# Operator contact for Let's Encrypt; also used for expiry warnings.
|
|
email {$ACME_EMAIL}
|
|
|
|
# Skip the HTTP-to-HTTPS redirect server (we have nothing to redirect).
|
|
# Caddy still binds :443 inside the container for the cert site, which
|
|
# is fine because we don't publish those ports to the host.
|
|
auto_https disable_redirects
|
|
}
|
|
|
|
{$CADDY_HOSTNAME} {
|
|
tls {
|
|
# DNS-01 challenge via Vultr API. The plugin reads the token from
|
|
# the named env var; setting via {env.VULTR_API_KEY} would also
|
|
# work but the bare reference is clearer with Caddy's modules.
|
|
dns vultr {env.VULTR_API_KEY}
|
|
|
|
# Use PUBLIC resolvers for the propagation check, not Docker's
|
|
# embedded DNS. Without this, Caddy follows the container's
|
|
# resolv.conf → host's resolv.conf → local LAN resolvers, which
|
|
# on a split-horizon DNS setup will return LAN IPs for vultr.com
|
|
# nameservers and the propagation check fails with connection
|
|
# refused. Hitting 1.1.1.1 / 9.9.9.9 directly sidesteps it.
|
|
resolvers 1.1.1.1 9.9.9.9 1.0.0.1
|
|
|
|
# Vultr's NS propagation is generally fast (<30s) but LE checks
|
|
# multiple resolvers; cushion the wait to avoid flaky issuance.
|
|
propagation_delay 30s
|
|
propagation_timeout 300s
|
|
}
|
|
|
|
# A sensible response if anyone hits this on 443. Doubles as a
|
|
# "Caddy is alive" sanity check inside the compose network.
|
|
respond "CoreDNS DoT/DoH endpoint. DoT: port 853. DoH: /dns-query" 200
|
|
}
|