Custom message when web server/site is down

1. The problem I’m having:

I would like to create a custom pages that states that the site is down, or some such, in the event my web server(s) is down or web services on that web server is down.
Since, for now, I have two sites on two separate servers I would like to create a custom maintenance page for each site.
I’ve searched the forum and other sites but have not been able to get this working. And, I am not a developer so understanding what code needs to be placed in the Caddyfile is confusing to me from the documentation.
I would like to have a custom maintenance file in the following locations on the proxy server:
/etc/caddy/maintenance1.html
/etc/caddy/maintenance2.html

Thanks.

2. Error messages and/or full log output:

PASTE OVER THIS, BETWEEN THE ``` LINES.
Please use the preview pane to ensure it looks nice.

3. Caddy version:

v2.9.1

4. How I installed and ran Caddy:

dnf install from copr repo

a. System environment:

Caddy is running on a RHEL 9.5 server dedicate proxy server. There are two sites served in Caddy. One site is currently running on a production (RHEL 9.5) Apache web server; second site is currently running on a separate test (RHEL 9.5) Apache web server.

b. Command:

systemctl enable --now caddy

c. Service/unit/compose file:

PASTE OVER THIS, BETWEEN THE ``` LINES.
Please use the preview pane to ensure it looks nice.

d. My complete Caddy config:

{
        debug
}

################################################################
www.androidsdream.net {
        # Enable the static file server.
        #        file_server

        reverse_proxy webserverip_1:80

        log {
                output file /var/log/caddy/access.log {
                        roll_size 1gb
                        roll_keep 5
                        roll_keep_for 720h
                }
        }
}

androidsdream.net {
        redir https://www.androidsdream.net{uri}
}

################################################################
www.edscloud.org {
        # Enable the static file server.
        file_server

        reverse_proxy webserverip_2:80
}

edscloud.org {
        redir https://www.edscloud.org{uri}
}

5. Links to relevant resources:

Adjust to your needs:

{
	http_port 8080
}

:8080 {
	reverse_proxy {
		## Main site first
		to http://localhost:8181
		## Maintenance site last
		to http://localhost:8282

		## Load balancing policy - always show the main site unless it's down
		lb_policy first

		## Health checks
		health_uri /
		health_status 2xx

		## Match responses that are served by the maintenance site and make them 503
		@maintenance {
			header X-Maintenance-Site true
		}
		replace_status @maintenance 503
	}
}

http://localhost:8181 {
	respond "Main Site"
}

http://localhost:8282 {
	header X-Maintenance-Site true
	respond "Maintenance Site"
}
$ caddy run --config Caddyfile
$ curl http://localhost:8080
Main Site

If you want to simulate the main site being down, just comment out the main site:

# http://localhost:8181 {
# 	respond "Main Site"
# }
$ caddy run --config Caddyfile
$ curl http://localhost:8080
Maintenance Site

See Load Balancing for more details.

Edit: I made a couple of changes to make sure your site doesn’t get indexed by search engines when it’s in a maintenance mode.

2 Likes

But I’m not trying to load balance. These are two separate sites running on two separate web servers (I plan to consolidate both sites to one server later).

The load balancing is with the maintenance site. Load balancing feature is being used to monitor your site and automatically switch over to the maintenance site when your main site is down.

2 Likes

You can use handle_errors to do something different on 502

3 Likes

From what I can tell, though, from your example config is that there is an assumption that there is a web server also running on the proxy server too, right? I would have to install httpd services and configure both those local maintenance sites on port 8181 & 8282?

The handle_errors documentation is what I had originally found and was completely confused about it in the reading.

Does the handle_errors section go before each site in my config? Or, is it just once at the beginning of the config, before the first reverse proxy?

UPDATE:
I read the documentation closer (after a couple of cups of coffee) and through some steps of trial and error while reading journalctl and I have answered my own question that it is inserted in each site, right in the site reverse proxy section, like so:

www.edscloud.org
{

        # Enable the static file server.
        file_server

        reverse_proxy webserverip_2:80

handle_errors {
        rewrite * /maintenance.html
        templates
        file_server
}

}

edscloud.org
{
        redir https://www.edscloud.org{uri}
}

However, when I stopped the web serives on the server hosting that site there is just a blank white page. It seems that it does not read the /maintenance.html that is located in /etc/caddy/ directory. Is it because it is an html file and web services are not running on the proxy server? How do I server a custom maintenance page that will be displayed instead of a blank white page? Can that maintenance.html be a simple text file instead?

Troubleshooting more with trial and error and came up with this that seems to work:

{
        debug
}

################################################################
www.androidsdream.net {
        # Enable the static file server.
        #        file_server

        reverse_proxy webserverip_1:80

        log {
                output file /var/log/caddy/access.log {
                        roll_size 1gb
                        roll_keep 5
                        roll_keep_for 720h
                }
        }
        handle_errors {
                respond "The site is down for maintenance"
        }
}

androidsdream.net {
        redir https://www.androidsdream.net{uri}
}

################################################################
www.edscloud.org {
        # Enable the static file server.
        file_server

        reverse_proxy webserverip_2:80

        handle_errors {
                respond "The site is down for maintenance"
        }
}

edscloud.org {
        redir https://www.edscloud.org{uri}
}

Any tips for improvements are welcomed.

No, that was just a quick example I put together on my laptop to show you how to use the load balancing feature for an automatic maintenance page. The web servers can be wherever you want - that’s why I started with “Adjust to your needs.”

2 Likes

You’re missing root definition here. handle_errors expects root to be either defined as part of the website configuration, or you need to define it inside the handle_error directive:

Note that file_server preserves the error’s HTTP status code when run in handle_errors (assumes you set a site root in your site beforehand)

Also, I’d recommend using

handle_errors 5xx {

rather than just simple

handle_errors {

otherwise you’ll be showing your maintenance page every time there’s a file missing on your main site, etc.

4 Likes