Closing a site for maintenance using HaProxy
Say you have a website running behind haproxy, and you want to block access to the backend for everyone except yourself, so you can perform some maintenance.
People visiting the website during maintenance should be served a special maintenance page, with a HTTP 503 response code, to indicate that the site is temporarily unavailable. You want this page to be different from the regular 503 error page, so that it's clear that it's planned maintenance.
I found that an easy way to achieve this is to use a separate 'maintenance' backend which is disabled by default, but which can be enabled using the haproxy's stats socket interface.
backend maintenance
server maintenance dummy:8090 disabled weight 0
errorfile 503 /path_to_maintenance_file/503_maintenance.httpThis backend has one server, but it has weight 0, which means this backend will always be 'down', resulting in a 503 response.
To direct traffic to this backend, we use some ACL rules in the frontend:
frontend main *:80
default_backend app-servers
acl maintenance_mode srv_is_up(maintenance/maintenance)
acl is_admin src 123.123.123.123
use_backend maintenance if maintenance_mode !is_adminNow if the maintenance backend is up, haproxy will use that instead of the default backend, except when the request is from 123.123.123.123 (obviously this should be the ip address of your own machine that you want to perform maintenance from).
Now all we have to do to switch to 'maintenance mode' is enable the maintenance/maintenance server:
echo 'enable server maintenance/maintenance' | socat unix-connect:/var/lib/haproxy/stats stdio
Note that you need HaProxy 1.4 for this, and your socket needs to be configured for level 'admin'.
