docker.recipes

Caddy Reverse Proxy Stack

intermediate

Caddy with automatic HTTPS and multiple backends.

Overview

Caddy is a modern, open-source web server developed in Go that revolutionizes web server management with its automatic HTTPS capabilities and zero-configuration approach. Unlike traditional web servers like Apache or Nginx that require complex SSL certificate management, Caddy automatically obtains, renews, and configures Let's Encrypt certificates, making HTTPS deployment effortless for developers and system administrators. This stack combines Caddy's powerful reverse proxy functionality with multiple whoami backend services, creating a robust load-balancing solution that demonstrates real-world reverse proxy patterns. The whoami containers serve as lightweight HTTP services that return request information, making them perfect for testing load distribution, health checks, and reverse proxy behavior. This configuration showcases Caddy's built-in load balancing capabilities across multiple backend services while maintaining automatic HTTPS termination at the proxy level. DevOps teams managing multiple microservices, developers building distributed applications, and organizations transitioning from complex reverse proxy setups will find this stack particularly valuable. The combination eliminates the need for separate load balancers or complex SSL certificate orchestration tools, providing a single-binary solution that handles both reverse proxying and automatic certificate management with minimal operational overhead.

Key Features

  • Automatic Let's Encrypt certificate provisioning and renewal with zero manual intervention
  • Built-in load balancing across multiple backend services with configurable algorithms
  • Zero-downtime configuration reloads through Caddy's live config API
  • HTTP/3 and HTTP/2 support with automatic protocol negotiation
  • On-demand TLS certificate generation for dynamic domain scenarios
  • Intelligent health checking and automatic backend failover
  • Real-time request information display through whoami service integration
  • Single binary deployment with no external dependencies or plugins required

Common Use Cases

  • 1Multi-tenant SaaS applications requiring automatic subdomain SSL certificate management
  • 2Development and staging environments for testing load balancing strategies
  • 3Microservices architecture with multiple backend services behind a single entry point
  • 4Legacy application modernization where HTTPS needs to be added without backend changes
  • 5Homelab setups requiring reverse proxy for multiple self-hosted services
  • 6DevOps training environments for teaching reverse proxy and load balancing concepts
  • 7API gateway replacement for simpler architectures not requiring complex routing logic

Prerequisites

  • Minimum 256MB RAM available for Caddy proxy operations and certificate management
  • Domain name with DNS control for automatic Let's Encrypt certificate validation
  • Ports 80 and 443 available and accessible from the internet for HTTPS challenges
  • Basic understanding of reverse proxy concepts and HTTP request routing
  • Docker host with internet connectivity for Let's Encrypt ACME challenges
  • Understanding of Caddyfile syntax for configuring routing rules and backend targets

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:alpine
4 container_name: caddy-proxy
5 restart: unless-stopped
6 ports:
7 - "${CADDY_HTTP_PORT:-80}:80"
8 - "${CADDY_HTTPS_PORT:-443}:443"
9 volumes:
10 - ./Caddyfile:/etc/caddy/Caddyfile:ro
11 - caddy_data:/data
12 - caddy_config:/config
13
14 backend-1:
15 image: traefik/whoami:latest
16 container_name: backend-1
17 restart: unless-stopped
18
19 backend-2:
20 image: traefik/whoami:latest
21 container_name: backend-2
22 restart: unless-stopped
23
24 backend-3:
25 image: traefik/whoami:latest
26 container_name: backend-3
27 restart: unless-stopped
28
29volumes:
30 caddy_data:
31 caddy_config:

.env Template

.env
1# Caddy Proxy
2CADDY_HTTP_PORT=80
3CADDY_HTTPS_PORT=443

Usage Notes

  1. 1Caddy at http://localhost
  2. 2Configure Caddyfile for routing
  3. 3Automatic HTTPS with Let's Encrypt
  4. 4Load balancing built-in

Individual Services(4 services)

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

caddy
caddy:
  image: caddy:alpine
  container_name: caddy-proxy
  restart: unless-stopped
  ports:
    - ${CADDY_HTTP_PORT:-80}:80
    - ${CADDY_HTTPS_PORT:-443}:443
  volumes:
    - ./Caddyfile:/etc/caddy/Caddyfile:ro
    - caddy_data:/data
    - caddy_config:/config
backend-1
backend-1:
  image: traefik/whoami:latest
  container_name: backend-1
  restart: unless-stopped
backend-2
backend-2:
  image: traefik/whoami:latest
  container_name: backend-2
  restart: unless-stopped
backend-3
backend-3:
  image: traefik/whoami:latest
  container_name: backend-3
  restart: unless-stopped

Quick Start

terminal
1# 1. Create the compose file
2cat > docker-compose.yml << 'EOF'
3services:
4 caddy:
5 image: caddy:alpine
6 container_name: caddy-proxy
7 restart: unless-stopped
8 ports:
9 - "${CADDY_HTTP_PORT:-80}:80"
10 - "${CADDY_HTTPS_PORT:-443}:443"
11 volumes:
12 - ./Caddyfile:/etc/caddy/Caddyfile:ro
13 - caddy_data:/data
14 - caddy_config:/config
15
16 backend-1:
17 image: traefik/whoami:latest
18 container_name: backend-1
19 restart: unless-stopped
20
21 backend-2:
22 image: traefik/whoami:latest
23 container_name: backend-2
24 restart: unless-stopped
25
26 backend-3:
27 image: traefik/whoami:latest
28 container_name: backend-3
29 restart: unless-stopped
30
31volumes:
32 caddy_data:
33 caddy_config:
34EOF
35
36# 2. Create the .env file
37cat > .env << 'EOF'
38# Caddy Proxy
39CADDY_HTTP_PORT=80
40CADDY_HTTPS_PORT=443
41EOF
42
43# 3. Start the services
44docker compose up -d
45
46# 4. View logs
47docker 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-reverse-proxy-stack/run | bash

Troubleshooting

  • Certificate validation failed: Ensure DNS records point to your server and ports 80/443 are publicly accessible for Let's Encrypt validation
  • Backend connection refused: Verify whoami containers are running and accessible within Docker network using docker exec to test connectivity
  • Caddyfile parse error on startup: Check Caddyfile syntax and ensure proper indentation, as Caddy is sensitive to configuration format
  • Load balancing not working: Confirm all backend services are defined in Caddyfile upstream block and containers are healthy
  • Permission denied accessing Caddyfile: Verify file ownership and that Caddyfile has proper read permissions for the caddy user inside container
  • Certificate storage issues: Check that caddy_data volume has sufficient space and proper write permissions for certificate storage

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