Manual SSL certificate generation, CSR generation, and cron-based renewals are completely obsolete. Modern homelab and production environments automate 100% of the certificate lifecycle using ACME challenge protocols.
This guide explains how to configure DNS-01 ACME challenges using Caddy and the Cloudflare API to issue wildcard certificates (e.g. *.homelab.example.com) without exposing port 80 or 443 to the public internet.
⚡ Quick Runbook: 60-Second Implementation
TL;DR: Deploy Caddy with the Cloudflare DNS module for fully automated wildcard certificates:
# compose.yaml
services:
caddy:
image: caddy:2.8-alpine
restart: unless-stopped
ports:
- "80:80"
- "443:443"
environment:
- CLOUDFLARE_API_TOKEN_FILE=/run/secrets/cf_token
secrets:
- cf_token
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- caddy_data:/data
- caddy_config:/config
secrets:
cf_token:
file: ./secrets/cf_token.txt
volumes:
caddy_data:
caddy_config:
1. Why DNS-01 Challenges Are Essential for Private Homelabs
- HTTP-01 Challenges: Require your server to have port 80 open to the public internet so Let’s Encrypt can reach a temporary challenge file. This is incompatible with private LANs, internal homelabs, and CGNAT connections.
- DNS-01 Challenges: Prove domain ownership by creating a temporary TXT record in your DNS provider (e.g. Cloudflare) via API. Zero open inbound firewall ports are required, and wildcard certificates (covering all subdomains under a single certificate) become possible.
2. Caddyfile Configuration for Cloudflare DNS-01 Wildcards
In your Caddyfile, specify the Cloudflare DNS provider inside the tls block:
# Global configuration
{
email [email protected]
}
# Wildcard Certificate for All Homelab Services
*.homelab.example.com {
tls {
dns cloudflare {env.CLOUDFLARE_API_TOKEN}
}
@vault host vault.homelab.example.com
handle @vault {
reverse_proxy vaultwarden:80
}
@git host git.homelab.example.com
handle @git {
reverse_proxy forgejo:3000
}
handle {
respond "Unauthorized" 401
}
}
3. Securing Your Cloudflare API Token
Follow the principle of least privilege when generating your Cloudflare API token:
- Navigate to Cloudflare Dashboard > My Profile > API Tokens.
- Click Create Token and choose the Edit zone DNS template.
- Under Zone Resources, select Specific zone and choose only your target domain.
- Save the token into a secure file (e.g.,
./secrets/cf_token.txt) with restrictive permissions (chmod 600) and mount it as a Docker secret.
Related Runbooks in This Series
- Base Linux OS Hardening: SSH Ed25519, UFW/nftables & Sysctl Baseline
- Fleet-Wide Intrusion Prevention: Deploying CrowdSec with Docker, Caddy & Firewall Bouncers
- Deploying a Secure WireGuard & Tailscale Exit Node on a VPS for Private Mobile Egress
- Zero-Trust Edge Ingress: Deploying Cloudflare Tunnels for Private Services
- Modern Reverse Proxy Architecture: Caddy Server & Cloudflare Tunnels for Container Ingress