docker.recipes

Caddy Reverse Proxy Stack

beginner

Automatic HTTPS reverse proxy with Caddy, built-in certificate management.

Overview

Caddy is a modern, enterprise-ready web server that revolutionized HTTPS deployment by automatically obtaining and renewing TLS certificates from Let's Encrypt. Unlike traditional web servers that require complex SSL configuration, Caddy handles certificate management transparently, making secure web hosting accessible to developers without extensive DevOps experience. Its simple Caddyfile syntax and built-in reverse proxy capabilities have made it increasingly popular for microservices architectures and containerized deployments. This deployment creates a complete reverse proxy monitoring stack with three distinct services: Caddy as the main reverse proxy server with automatic HTTPS, a whoami service that provides request information for testing and debugging proxy configurations, and Prometheus for collecting and storing metrics from the infrastructure. The whoami service acts as a sample backend application, demonstrating how Caddy routes traffic to upstream services while providing useful diagnostic information about incoming requests. This configuration is ideal for developers and small teams who want to establish a production-ready reverse proxy with built-in monitoring capabilities. The combination provides both the simplicity of Caddy's automatic HTTPS with the observability power of Prometheus, making it perfect for homelab environments, development teams setting up staging environments, or small businesses needing reliable web traffic routing without the complexity of enterprise solutions like NGINX Plus or commercial load balancers.

Key Features

  • Automatic HTTPS certificate provisioning and renewal via Let's Encrypt with zero manual intervention
  • HTTP/3 and HTTP/2 support enabled by default for optimal web performance
  • Real-time Caddyfile configuration reloading without service interruption or dropped connections
  • Built-in whoami service for testing proxy routes and debugging request headers
  • Prometheus metrics collection with persistent storage for long-term monitoring trends
  • Zero-configuration service discovery within the Docker network for backend routing
  • On-demand TLS certificate generation for dynamic subdomain scenarios
  • Comprehensive request logging and health check endpoints across all services

Common Use Cases

  • 1Development teams needing HTTPS-enabled staging environments with minimal configuration overhead
  • 2Homelab enthusiasts running multiple self-hosted services behind a single domain with automatic SSL
  • 3Small businesses migrating from shared hosting to containerized infrastructure with monitoring
  • 4DevOps engineers prototyping reverse proxy configurations before implementing enterprise solutions
  • 5Educational environments teaching modern web architecture and certificate management concepts
  • 6Startups requiring quick deployment of secure web services with built-in observability
  • 7API gateway scenarios where automatic HTTPS and request monitoring are essential requirements

Prerequisites

  • Domain name with DNS pointing to your server for Let's Encrypt certificate validation
  • Minimum 512MB RAM available (256MB for Caddy, 256MB for Prometheus base operation)
  • Ports 80, 443, 443/UDP, and 9090 available and accessible from the internet
  • Basic understanding of reverse proxy concepts and upstream service configuration
  • Email address for Let's Encrypt certificate registration and renewal notifications
  • Docker Compose v2.0+ with support for UDP port mapping and named volumes

For development & testing. Review security settings, change default credentials, and test thoroughly before production use. See Terms

docker-compose.yml

docker-compose.yml
1services:
2 caddy:
3 image: caddy:latest
4 ports:
5 - "80:80"
6 - "443:443"
7 - "443:443/udp"
8 volumes:
9 - ./Caddyfile:/etc/caddy/Caddyfile:ro
10 - caddy_data:/data
11 - caddy_config:/config
12 environment:
13 - DOMAIN=${DOMAIN}
14 - EMAIL=${EMAIL}
15 networks:
16 - caddy-net
17 restart: unless-stopped
18
19 whoami:
20 image: traefik/whoami:latest
21 networks:
22 - caddy-net
23 restart: unless-stopped
24
25 prometheus:
26 image: prom/prometheus:latest
27 ports:
28 - "9090:9090"
29 volumes:
30 - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
31 - prometheus_data:/prometheus
32 networks:
33 - caddy-net
34 restart: unless-stopped
35
36volumes:
37 caddy_data:
38 caddy_config:
39 prometheus_data:
40
41networks:
42 caddy-net:
43 driver: bridge

.env Template

.env
1# Caddy Configuration
2DOMAIN=example.com
3EMAIL=admin@example.com

Usage Notes

  1. 1Create Caddyfile with your reverse proxy config
  2. 2Automatic HTTPS with Let's Encrypt
  3. 3HTTP/3 support out of the box
  4. 4Simple configuration syntax

Individual Services(3 services)

Copy individual services to mix and match with your existing compose files.

caddy
caddy:
  image: caddy:latest
  ports:
    - "80:80"
    - "443:443"
    - 443:443/udp
  volumes:
    - ./Caddyfile:/etc/caddy/Caddyfile:ro
    - caddy_data:/data
    - caddy_config:/config
  environment:
    - DOMAIN=${DOMAIN}
    - EMAIL=${EMAIL}
  networks:
    - caddy-net
  restart: unless-stopped
whoami
whoami:
  image: traefik/whoami:latest
  networks:
    - caddy-net
  restart: unless-stopped
prometheus
prometheus:
  image: prom/prometheus:latest
  ports:
    - "9090:9090"
  volumes:
    - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
    - prometheus_data:/prometheus
  networks:
    - caddy-net
  restart: unless-stopped

Quick Start

terminal
1# 1. Create the compose file
2cat > docker-compose.yml << 'EOF'
3services:
4 caddy:
5 image: caddy:latest
6 ports:
7 - "80:80"
8 - "443:443"
9 - "443:443/udp"
10 volumes:
11 - ./Caddyfile:/etc/caddy/Caddyfile:ro
12 - caddy_data:/data
13 - caddy_config:/config
14 environment:
15 - DOMAIN=${DOMAIN}
16 - EMAIL=${EMAIL}
17 networks:
18 - caddy-net
19 restart: unless-stopped
20
21 whoami:
22 image: traefik/whoami:latest
23 networks:
24 - caddy-net
25 restart: unless-stopped
26
27 prometheus:
28 image: prom/prometheus:latest
29 ports:
30 - "9090:9090"
31 volumes:
32 - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
33 - prometheus_data:/prometheus
34 networks:
35 - caddy-net
36 restart: unless-stopped
37
38volumes:
39 caddy_data:
40 caddy_config:
41 prometheus_data:
42
43networks:
44 caddy-net:
45 driver: bridge
46EOF
47
48# 2. Create the .env file
49cat > .env << 'EOF'
50# Caddy Configuration
51DOMAIN=example.com
52EMAIL=admin@example.com
53EOF
54
55# 3. Start the services
56docker compose up -d
57
58# 4. View logs
59docker compose logs -f

One-Liner

Run this command to download and set up the recipe in one step:

terminal
1curl -fsSL https://docker.recipes/api/recipes/caddy-proxy-stack/run | bash

Troubleshooting

  • Certificate provisioning failed: Verify DNS points to server and ports 80/443 are accessible from internet
  • Caddy service fails to start: Check Caddyfile syntax and ensure DOMAIN environment variable is properly set
  • Prometheus data not persisting: Verify prometheus_data volume has correct permissions (UID 65534 for nobody user)
  • Whoami service returns 502 errors: Confirm all services are on caddy-net network and container names match Caddyfile upstream definitions
  • HTTP/3 not working: Ensure port 443/UDP is open in firewall and client supports QUIC protocol
  • Let's Encrypt rate limiting errors: Check certificate request frequency and consider using staging ACME server for testing

Community Notes

Loading...
Loading notes...

Download Recipe Kit

Get all files in a ready-to-deploy package

Includes docker-compose.yml, .env template, README, and license

Ad Space