Skip to main content

Step 3

Step 3 — Caddy automatic HTTPS

4 views

Table of contents

Like Nginx, but automatic HTTPS out of the box. Caddy fetches and renews Let's Encrypt certificates for you.

Three lines per domain

example.com {
    reverse_proxy app:3000
}

That's it — automatic HTTPS, 80→443 redirect, compression.

Multiple subdomains

api.example.com    { reverse_proxy backend:8080 }
example.com        { reverse_proxy frontend:3000 }
admin.example.com  { reverse_proxy admin:3000 }

One 80/443 pair, many services.

docker-compose integration

services:
  caddy:
    image: caddy:2-alpine
    ports: ["80:80", "443:443"]
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - caddy-data:/data
      - caddy-config:/config
    restart: unless-stopped

  app:
    build: .
    expose: ["3000"]   # Caddy only

volumes:
  caddy-data:
  caddy-config:

caddy-data must be a named volume — losing it can hit Let's Encrypt rate limits.

Forwarding headers

example.com {
    reverse_proxy app:3000 {
        header_up Host {host}
        header_up X-Forwarded-Host {host}
        header_up X-Forwarded-Proto {scheme}
        header_up X-Forwarded-Port "443"
    }
}

Five operational tips

  1. Never delete caddy-data (cert cache)
  2. Local self-signed: tls internal
  3. Reload: docker exec caddy caddy reload or restart
  4. One Caddy can host dozens of domains
  5. Access logs: log { output file /var/log/access.log }

Try it

Prepare a free or low-cost DNS name such as yourname.example.org, deploy with the YAML above, and open it over HTTPS. The padlock icon means Caddy is doing its job.

Going deeper

Next

Step 4 — minimize external surface with SSH tunnels.