Back to DevOpsForge Visual Builder
Infrastructure Architecture

Caddy Reverse Proxy with Docker Compose (Auto-SSL & HTTP/3)

Updated September 2026 Caddy v2.7+ Automatic HTTPS & Let's Encrypt

Traditional web servers like Nginx require external sidecar containers (like Certbot or `nginx-proxy-manager`) to obtain and renew Let's Encrypt TLS certificates. Caddy solves this entirely by managing ACME certificates, HTTPS redirects, and HTTP/3 multiplexing natively in a single container.

This guide demonstrates how to configure Caddy in Docker Compose to securely reverse-proxy upstream web services with security headers, Gzip compression, and rate limiting.

Build Full Multi-Container Stacks with Caddy

Generate production Docker Compose bundles with Caddy proxying Node, Python, PHP, or Go apps visually.

1. The Production `Caddyfile`

Replace api.yourdomain.com with your domain name. Ensure your domain points to your VPS public IP before starting the container.

Caddyfile
api.yourdomain.com {
    # Enable Gzip and Zstandard compression
    encode gzip zstd

    # Route incoming requests to your app container
    reverse_proxy app:3000 {
        header_up X-Real-IP {remote_host}
        header_up X-Forwarded-For {remote_host}
        header_up X-Forwarded-Proto {scheme}
    }

    # Hardened Security Headers
    header {
        Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
        X-Content-Type-Options "nosniff"
        X-Frame-Options "DENY"
        Referrer-Policy "strict-origin-when-cross-origin"
        Permissions-Policy "camera=(), microphone=(), geolocation=()"
    }
}

2. `docker-compose.yml` for Caddy

Two persistent Docker volumes (caddy_data and caddy_config) must be mounted to prevent rate-limiting by Let's Encrypt on container restarts.

docker-compose.yml
version: '3.8'

services:
  caddy:
    image: caddy:2-alpine
    container_name: caddy_proxy
    restart: always
    ports:
      - "80:80"
      - "443:443"
      - "443:443/udp" # Required for HTTP/3 QUIC
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - caddy_data:/data       # Preserves SSL certificates
      - caddy_config:/config   # Preserves runtime config
    networks:
      - webnet

  app:
    image: your-app-image:latest
    container_name: web_app
    restart: always
    expose:
      - "3000"
    networks:
      - webnet

networks:
  webnet:

volumes:
  caddy_data:
  caddy_config: