Reverse Proxy and TLS covered getting a single Let's Encrypt certificate via ACME, using either an HTTP or DNS challenge. That's enough for a handful of services. This page is about what changes once you have a dozen-plus internal-only hostnames and public ACME starts feeling like the wrong shape for the problem.

Where the single-certificate model starts to strain

Requesting one certificate per hostname works fine at small scale, but two things push people toward a different approach as a homelab grows:

  • Let's Encrypt rate limits - generous, but per-domain limits on certificates issued per week exist, and hitting them mid-experiment (spinning up and tearing down test hostnames repeatedly) is a common homelab annoyance.
  • HTTP-01 challenges require public reachability for each hostname, which doesn't work for services you never intend to expose
    • and running a DNS-01 challenge per-hostname means your reverse proxy needs API credentials for your DNS provider for every single certificate request.

Request a single certificate for *.yourdomain.com using a DNS-01 challenge, then reuse it across every internal hostname (jellyfin.yourdomain.com, vault.yourdomain.com, and so on) without requesting a new certificate per service. Caddy and Traefik both support this directly - Caddy in particular makes wildcard DNS-01 nearly automatic once your DNS provider's API token is configured once.

*.yourdomain.com {
    tls {
        dns cloudflare {env.CLOUDFLARE_API_TOKEN}
    }
    respond "configure per-service routing below"
}

This is the right default for most homelabs: real, browser-trusted certificates, no per-service public exposure required, one API token to manage instead of many. The trade-off is that the DNS API token itself becomes a sensitive credential worth real protection - see Secrets Management for storing it properly rather than in a plaintext .env file sitting in a repo.

Option 2: run your own internal CA

An internal CA (certificate authority) issues its own certificates that only your devices trust, because you've explicitly installed its root certificate on each of them. step-ca (Smallstep) is the most homelab-friendly option - it can issue short-lived certificates automatically via its own ACME-compatible endpoint, so your reverse proxy config barely changes from the public-ACME setup, just pointed at your internal CA instead of Let's Encrypt.

This avoids any dependency on a public domain or external DNS API entirely, and works for fully offline/air-gapped setups. The real cost is trust distribution and revocation: every device that needs to trust these certificates without a warning needs your root CA certificate installed manually, and if your root CA's private key is ever compromised, every certificate it ever issued is suspect until you rotate it and redistribute the new root to every device again.

⚠️ Risk: an internal CA's root private key is one of the highest-value secrets in your entire homelab - anyone who obtains it can mint a trusted certificate for any hostname your devices accept. Store it with the same rigor as anything else in Secrets Management, and treat losing it as equivalent to needing to re-trust every device from scratch.

Which to actually pick

Wildcard DNS-01 through a public domain for almost everyone - it's simpler to operate, doesn't require managing your own PKI, and your devices trust it automatically with zero per-device setup. Reach for an internal CA specifically if you're offline-first with no public domain at all, or if running real PKI is itself something you want to learn - a legitimate reason on its own, just not a default recommendation.

Next: Secrets Management.