http.handlers.reverse_proxy
Overview
Upon proxying, the reverse proxy sets placeholders that can be used in subsequent handlers or logging:| Placeholder | Description |
|---|---|
{http.reverse_proxy.upstream.address} | Full address to the upstream as given in config |
{http.reverse_proxy.upstream.hostport} | Host:port of the upstream |
{http.reverse_proxy.upstream.host} | Host of the upstream |
{http.reverse_proxy.upstream.port} | Port of the upstream |
{http.reverse_proxy.upstream.requests} | Approximate current number of requests to the upstream |
{http.reverse_proxy.upstream.max_requests} | Maximum approximate number of requests allowed |
{http.reverse_proxy.upstream.fails} | Number of recent failed requests |
{http.reverse_proxy.upstream.latency} | Time for upstream to write response header |
{http.reverse_proxy.upstream.latency_ms} | Same as latency, but in milliseconds |
{http.reverse_proxy.upstream.duration} | Time spent proxying, including writing response body |
{http.reverse_proxy.upstream.duration_ms} | Same as duration, but in milliseconds |
{http.reverse_proxy.duration} | Total time spent proxying, including retries |
{http.reverse_proxy.duration_ms} | Same as duration, but in milliseconds |
{http.reverse_proxy.retries} | Number of retries actually performed |
Basic Configuration
Static list of backends to proxy to.
The address to dial to reach the upstream. Supports placeholders and network addresses.Examples:
localhost:8080192.168.1.10:9000unix//var/run/app.sock
Maximum concurrent requests to this upstream. If exceeded, the upstream is considered unhealthy.
Module for retrieving the list of upstreams dynamically. Dynamic upstreams are retrieved at every iteration of the proxy loop for each request.Module namespace:
Active health checks do not work on dynamic upstreams. Passive health checks are only effective if the proxy is busy enough that concurrent requests to the same backends are continuous.
http.reverse_proxy.upstreamsTransport
Configures the method of transport for the proxy. A transport performs the actual “round trip” to the backend. The default is plaintext HTTP.Module namespace:
http.reverse_proxy.transportAvailable transports:http- Standard HTTP transport (default)fastcgi- FastCGI transport for PHP and other applications
Load Balancing
Distributes load/requests between backends.
How to select an upstream from the pool. Default is
random.Available policies:random- Select randomlyrandom_choose- Select N randomly, pick least loadedleast_conn- Pick upstream with fewest active requestsround_robin- Cycle through upstreams sequentiallyweighted_round_robin- Round robin with weightsfirst- Select first availableip_hash- Hash based on client IPclient_ip_hash- Hash based on trusted client IPuri_hash- Hash based on request URIquery- Hash based on query parameterheader- Hash based on request headercookie- Hash based on cookie (with sticky sessions)
How long to try selecting available backends for each request.
How long to wait between selecting the next host when retrying.
Maximum number of retries (not counting the first attempt).
Request matcher for determining which requests are idempotent and safe to retry. By default, only GET requests are retried.
Health Checks
Configures active and passive health checks.
Active Health Checks
Run in the background on a timer. Do not work for dynamic upstreams.
The URI (path and query) to use for health checks.
Alternative port to use for health checks (if different from upstream dial address).
HTTP headers to set on health check requests.
How frequently to perform active health checks.
How long to wait for a response before considering the backend unhealthy.
Number of consecutive passes before marking a previously unhealthy backend as healthy.
Number of consecutive failures before marking a previously healthy backend as unhealthy.
The HTTP status code to expect from a healthy backend.
Regular expression to match against the response body of a healthy backend.
Passive Health Checks
Monitor proxied requests for errors or timeouts. State is shared globally across all handlers.
How long to remember a failed request. Must be > 0 to enable passive health checks.
Number of failures within
fail_duration to mark a backend as down.Mark backend as down if it has this many concurrent requests or more.
HTTP status codes that count as failures.
Count request as failed if response takes at least this long.
Circuit Breaker
Acts as an early-warning system for health checks when backends are getting overloaded.Module namespace:
http.reverse_proxy.circuit_breakersHeaders
Manipulates headers between Caddy and the backend.By default, all headers are passed through without changes, except for special hop-by-hop headers.
X-Forwarded-For, X-Forwarded-Proto, and X-Forwarded-Host are set implicitly.Header operations to apply to the request before sending to upstream.
Header operations to apply to the response before sending to client.
IP ranges (CIDR notation) from which X-Forwarded-* header values should be trusted. By default, no proxies are trusted.
Request/Response Handling
Rewrites the copy of the upstream request. Allows changing the request method and URI.The rewrite is applied to the copy, so it doesn’t persist past the reverse proxy handler.If the method is changed to
GET or HEAD, the request body will not be copied to the backend.List of handlers to evaluate after successful roundtrips. The first handler that matches the response will be invoked.Three new placeholders available in this handler chain:
{http.reverse_proxy.status_code}- Status code from response{http.reverse_proxy.status_text}- Status text from response{http.reverse_proxy.header.*}- Headers from response
Buffering
If nonzero, the entire request body up to this size will be read and buffered in memory before being proxied.
This should be avoided if possible for performance reasons, but could be useful if the backend is intolerant of read latency or chunked encodings.
If nonzero, the entire response body up to this size will be read and buffered in memory before being proxied to the client.
How often to flush the response buffer. By default, no periodic flushing is done.A negative value disables response buffering and flushes immediately after each write.
Streaming
If nonzero, streaming requests such as WebSockets will be forcibly closed at the end of the timeout.
If nonzero, streaming requests will not be closed when the proxy config is unloaded. Instead, the stream will remain open until the delay is complete.This prevents streams from closing when Caddy’s config is reloaded, avoiding a thundering herd of reconnecting clients.
Configuration Examples
Basic Reverse Proxy
Multiple Upstreams with Load Balancing
With Health Checks
With Header Manipulation
The reverse proxy automatically adds
X-Forwarded-For, X-Forwarded-Proto, and X-Forwarded-Host headers unless explicitly configured otherwise.