Reverse Proxy backup/failover

1. Caddy version (caddy version):

$ caddy version
v2.5.1 h1:bAWwslD1jNeCzDa+jDCNwb8M3UJ2tPa8UZFFzPVmGKs=

2. How I run Caddy:

I am using Caddy as a reverse proxy to an upstream web server. The upstream web server is running PHP-FPM and I have configured Caddy to check the /ping endpoint (which, for reasons, I have exposed on port :81 on the upstream server).
This works as expected; based on the config below Caddy checks the upstream’s /ping every 10 seconds and reacts as expected when the /ping endpoint doesn’t respond healthy.

The functionality I would like to add is a backup/failover page that would respond in the event that all upstream servers are in an unhealthy state.
I am currently testing this with one upstream and then a “sorry the site is down” page that is served locally from the Caddy VM.

With my current config, Caddy correctly tries to check for the :81/ping endpoint on both the upstream and itself; however since I don’t have anything listening on :81 on the local Caddy VM, this fails the health checks.

Is there a way to perform normal reverse proxy health checks & load balancing and provide a ‘last resort’ upstream that would respond if no other upstreams are in a healthy state?

a. System environment:

Debian 11.3

b. Command:

# caddy run --watch
2022/07/07 21:15:20.243 INFO    using adjacent Caddyfile 

c. Service/unit/compose file:

n/a (but I just use the one from the Caddy Debian repo)

d. My complete Caddyfile or JSON config:

:8080 {
	respond "The site you are attempting to connect to is currently unavailable" 504
} {
	reverse_proxy {
		to http://localhost:8080

		lb_policy first

		header_down "X-Served-By" "Edge05"
		flush_interval -1

		health_uri /ping
		health_port 81
		health_interval 60s
		health_timeout 10s
		health_status 200

3. The problem I’m having:

I would like my local ‘upstream-of-last-resort’ to be used when all other upstreams are unhealthy and not be subject to the health checks of the other upstreams.

4. Error messages and/or full log output:

2022/07/08 00:28:55.865 INFO       HTTP request failed     {"host": "localhost:81", "error": "Get \"http://localhost:81/ping\": dial tcp [::1]:81: connect: connection refused"}

5. What I already tried:

I know I can fake it by just having Caddy listen and respond 200 on :81/ping, but that just seems like a janky workaround that won’t scale well.

6. Links to relevant resources:

You can use handle_errors to set up routes to do whatever you want when an error is produced:

1 Like

This topic was automatically closed after 30 days. New replies are no longer allowed.