Work

HTTPS Caddy + Tailscale

Zero-config HTTPS for self-hosted services

Year
2024
Language
Docker
Stars
25
Topics
caddy docker docker-compose tailscale

Overview

A tiny Compose stack that turns any homelab service into a publicly reachable HTTPS endpoint without opening ports on a home router. Tailscale handles the network layer (mesh VPN, MagicDNS, ACL routing). Caddy fronts the services and provisions Let’s Encrypt certificates automatically. The whole setup is one `docker compose up` away.

Features

  • Automatic TLS certificates from Let’s Encrypt via Caddy ACME
  • Public HTTPS for any container, even on a residential CGNAT connection
  • No router port-forwarding — Tailscale handles ingress over its mesh
  • Single Caddyfile maps subdomains to upstream container ports
  • Works equally well on a Raspberry Pi or a cloud VM

Why it exists

Why this exists

Most home ISPs put residential connections behind carrier-grade NAT, which makes the textbook “forward port 443” approach impossible. Tailscale Funnel and HTTPS termination on a public node sidestep that — your traffic enters via Tailscale’s infra, gets routed over the mesh, and Caddy is the only thing that needs to know about certificates.

Why Caddy over nginx

Caddy provisions and renews ACME certificates without any extra cron jobs, certbot, or sidecar containers. The config syntax is short enough to fit a homelab use case in fewer than 30 lines, and the binary ships every batteries-included middleware (compression, security headers, HTTPS-by-default) on.

Tech stack

Networking
Tailscale MagicDNS Tailscale Funnel
Ingress
Caddy ACME / Let’s Encrypt
Runtime
Docker Docker Compose

Architecture

graph LR
  U["🌐 User"] -->|HTTPS| CF["Cloudflare DNS"]
  CF --> CD["Caddy<br/>Reverse Proxy"]
  CD -->|ACME| LE["Let's Encrypt"]
  CD -->|Tailscale Mesh| TS["Tailscale<br/>Network"]
  TS --> S1["Service A<br/>(container)"]
  TS --> S2["Service B<br/>(container)"]
  TS --> S3["Service C<br/>(container)"]
  classDef edge fill:#0a0a0a,stroke:#666,color:#fff
  classDef svc fill:#1e1e1e,stroke:#444,color:#ddd
  class U,CF edge
  class S1,S2,S3 svc
Architecture: HTTPS Caddy + Tailscale

Quick start

bash
									git clone https://github.com/nsudhanva/https-caddy-tailscale
cd https-caddy-tailscale
cp .env.example .env   # set TS_AUTHKEY, DOMAIN, EMAIL
docker compose up -d