This page provides an overview of Caddy's reverse proxy handler, which implements HTTP proxying capabilities including load balancing, health checks, and pluggable transports. The reverse proxy is registered as the http.handlers.reverse_proxy module and is implemented in the reverseproxy package.
For detailed information on specific subsystems:
Sources: modules/caddyhttp/reverseproxy/reverseproxy.go53-74
The reverse proxy is implemented as an HTTP handler that sits in the request processing chain. It selects an available upstream backend, proxies the request through a configurable transport, and handles responses with optional post-processing.
Reverse Proxy Module Structure
Sources: modules/caddyhttp/reverseproxy/reverseproxy.go420-520 modules/caddyhttp/reverseproxy/reverseproxy.go526-644
The Handler struct contains all configuration and runtime state for the reverse proxy. Key fields determine its behavior:
| Field | Type | Purpose |
|---|---|---|
Transport | http.RoundTripper | The transport implementation (HTTP, FastCGI, etc.) |
Upstreams | UpstreamPool | Static list of backend servers |
DynamicUpstreams | UpstreamSource | Module for retrieving upstreams dynamically |
LoadBalancing | *LoadBalancing | Load balancing policy and retry configuration |
HealthChecks | *HealthChecks | Active and passive health check configuration |
Headers | *headers.Handler | Request/response header manipulation |
HandleResponse | []caddyhttp.ResponseHandler | Custom response processing routes |
CB | CircuitBreaker | Circuit breaker for pressure relief |
TrustedProxies | []string | CIDR ranges of trusted proxies for forwarded headers |
Sources: modules/caddyhttp/reverseproxy/reverseproxy.go74-219
The reverse proxy processes requests through multiple stages with retry support.
Request Lifecycle Sequence
Sources: modules/caddyhttp/reverseproxy/reverseproxy.go420-520 modules/caddyhttp/reverseproxy/reverseproxy.go526-644 modules/caddyhttp/reverseproxy/reverseproxy.go677-792
The reverse proxy uses a two-level model to track backend state:
Upstream and Host Relationship
The Upstream struct represents a configured backend in a specific handler context. Each Upstream embeds a reference to a shared Host.
Key fields:
Dial: Network address (supports placeholders)MaxRequests: Per-upstream request limitHost: Reference to shared stateunhealthy: Atomic flag from active health checksKey methods:
Available(): Returns true if the upstream is healthy and not fullHealthy(): Checks circuit breaker, passive health, and active healthFull(): Returns true if NumRequests() >= MaxRequestsfillDialInfo(): Resolves placeholders to create a DialInfoSources: modules/caddyhttp/reverseproxy/hosts.go34-64 modules/caddyhttp/reverseproxy/hosts.go76-98 modules/caddyhttp/reverseproxy/hosts.go102-124
The Host struct maintains shared state for a backend address across all handlers. It is stored in the global hosts usage pool to preserve state through config reloads.
Atomic counters:
numRequests: Current active request countfails: Passive health check failure countactivePasses: Active health check consecutive passesactiveFails: Active health check consecutive failuresAll fields are accessed atomically via methods like NumRequests(), Fails(), countRequest(), countFail(), etc.
Sources: modules/caddyhttp/reverseproxy/hosts.go135-209 modules/caddyhttp/reverseproxy/hosts.go265-269
The reverse proxy uses the http.RoundTripper interface to abstract the protocol used to communicate with backends. This allows pluggable transports for different backend protocols.
Transport Types
Implements HTTP/HTTPS proxying with support for:
Module ID: http.reverse_proxy.transport.http
Sources: modules/caddyhttp/reverseproxy/httptransport.go52-165 modules/caddyhttp/reverseproxy/httptransport.go180-516
Implements the FastCGI protocol for communicating with PHP-FPM and similar backends. It builds CGI environment variables and handles the FastCGI wire protocol.
Key features:
SCRIPT_FILENAME and PATH_INFO construction.php suffix detection)Module ID: http.reverse_proxy.transport.fastcgi
Sources: modules/caddyhttp/reverseproxy/fastcgi/fastcgi.go50-96 modules/caddyhttp/reverseproxy/fastcgi/fastcgi.go162-256
The reverse proxy is configured through the reverse_proxy Caddyfile directive or JSON module. Configuration includes:
Main Configuration Areas
| Area | Description | Details |
|---|---|---|
| Upstreams | Backend servers | Static list via to or dynamic via dynamic |
| Load Balancing | Selection policy | See Upstream Selection and Load Balancing |
| Health Checks | Active/passive checks | See Health Checks and Circuit Breaking |
| Transport | Protocol configuration | See Transports |
| Headers | Request/response headers | header_up, header_down directives |
| Response Handling | Custom response routes | handle_response blocks with matchers |
| Streaming | Streaming configuration | flush_interval, stream_timeout |
Example Caddyfile Configuration:
Sources: modules/caddyhttp/reverseproxy/caddyfile.go58-133 modules/caddyhttp/reverseproxy/reverseproxy.go229-406
The reverse proxy sets several placeholders during request processing that can be used in configuration:
| Placeholder | Description |
|---|---|
{http.reverse_proxy.upstream.address} | Full upstream address from config |
{http.reverse_proxy.upstream.hostport} | Host:port of selected upstream |
{http.reverse_proxy.upstream.host} | Host portion |
{http.reverse_proxy.upstream.port} | Port portion |
{http.reverse_proxy.upstream.requests} | Current request count |
{http.reverse_proxy.upstream.max_requests} | Max requests limit |
{http.reverse_proxy.upstream.fails} | Failure count |
{http.reverse_proxy.upstream.latency} | Response header latency |
{http.reverse_proxy.upstream.duration} | Total proxy duration |
{http.reverse_proxy.duration} | Total duration including retries |
{http.reverse_proxy.retries} | Number of retries performed |
These placeholders are set in modules/caddyhttp/reverseproxy/reverseproxy.go588-595 and modules/caddyhttp/reverseproxy/reverseproxy.go983-984
Sources: modules/caddyhttp/reverseproxy/reverseproxy.go53-73 modules/caddyhttp/reverseproxy/reverseproxy.go588-595