Skip to content

Self-host Caddy

updated Sep 2026prices checked · Jul 2026
We earn commissions when you shop through the links below. Full disclosure →

A web server and reverse proxy with automatic HTTPS on by default: name a domain in a two-line Caddyfile and it obtains and renews the certificate from Let's Encrypt or ZeroSSL and redirects HTTP to HTTPS for you. A single Apache-2.0 Go binary with no external dependencies, HTTP/3 on by default, and a JSON admin API for zero-downtime config changes — no web UI and no container auto-discovery out of the box.

Key facts

LicenseApache-2.0
StackGo
Min RAM256 MB
Official imageyes
Difficulty
Our recommendation

Pick Caddy when you want automatic HTTPS with the least configuration of any proxy here: name a domain in the Caddyfile, point it at a backend, and Caddy obtains and renews the certificate from Let's Encrypt or ZeroSSL and redirects HTTP to HTTPS for you. It is a single Apache-2.0 Go binary with no external dependencies, and it doubles as a full static-file web server. If you would rather click than edit a file, Nginx Proxy Manager is the answer; if you want routes to follow Docker labels, Traefik is.

Follow the Caddy deploy guide →

What you need

  • Any VPS with at least 256 MB of RAM
  • A domain you control — most self-hosted setups need HTTPS in front of them
  • Under an hour if you've used Docker before
Where to host itaffiliate disclosure
Hetzner Cloudrun it on
From $23.59/mo · 2 vCPU / 4 GB / 80 GB · EU + US
Get Hetzner Cloud (opens in new tab)
Kamaterafree trial
From $4/mo · 1 vCPU / 1 GB / 20 GB · US + EU + Asia
Start free on Kamatera → (opens in new tab)
DigitalOceanalso works on
From $6/mo · 1 vCPU / 1 GB / 25 GB · US + EU + Asia
Deploy on DigitalOcean → (opens in new tab)

Paid link — we earn a commission if you shop through it.

Install with Docker Compose

Save this as compose.yml and run docker compose up -d:

# Caddy — official image; the Caddyfile lives in ./conf, certificates in the caddy_data volume
services:
  caddy:
    image: caddy:2
    restart: unless-stopped
    ports: ["80:80", "443:443", "443:443/udp"]
    volumes:
      - ./conf:/etc/caddy
      - caddy_data:/data
      - caddy_config:/config
volumes:
  caddy_data:
  caddy_config:
# ./conf/Caddyfile:  app.example.com { reverse_proxy app:3000 }  — then docker compose up -d

What you take on

Caddy's defaults are safe and few; the things worth knowing come from its own docs and its official Docker image:

non-negotiablePersist the data directory. The image docs are blunt that /data "must not be treated as a cache" — it holds certificates, private keys and OCSP staples. Lose it and every restart looks like a new install to the CA. Our snippet keeps it in the caddy_data volume; /config is optional to persist but convenient.
non-negotiableThe official image docs recommend mounting a directory at /etc/caddy rather than the Caddyfile itself: they warn that editors which replace the file's inode leave the container on the old config until it is recreated, and graceful reloads may not work. Reload with docker compose exec -w /etc/caddy caddy caddy reload.
non-negotiableThere is no Docker auto-discovery in the standard build: every site is one you add to the Caddyfile. The community caddy-docker-proxy plugin generates the Caddyfile from container labels, but it is a separate project, not part of Caddy.
non-negotiableWildcard certificates need the DNS challenge, and that needs a DNS provider module compiled in. Use the image's builder variant with xcaddy build --with <module> and copy the binary onto the regular image, as the image docs show.
non-negotiableThe admin API listens on localhost:2019 by default and applies config changes with zero downtime. If untrusted code shares the host, the docs suggest binding it to a permissioned unix socket instead. The 256 MB floor is our estimate; upstream publishes no RAM figure.

Head-to-head

More self-hosted tools

We use analytics cookies (Google Analytics, PostHog) to see which guides are useful. No ad networks, no cross-site tracking. See our privacy policy.