Sometimes we need to take our web apps offline temporarily. It could be to do a major upgrade or in an emergency situation. Anyways, you should at least set a static page to notify regular users that the site is currently unavailable. And it’s even better if you can maintain access for you and your fellow developers in the meantime.
Create a maintenance page
First step is to create a good maintenance page. Good means clean, simple, visually attractive and the most important thing: “self-contained” ! So any required resource should be embedded inside a “simple” HTML file.
How to do that ?
For CSS use the tag style
to integrate the content into the HTML like this:
<style media="screen" type="text/css">
... Add CSS data here ...
</style>
For images encode them in base64 using the base64
command and add the resulting string into the HTML like this:
<img src="data:image/gif;base64,BASE64STRING" alt="my_image" />
You have a good maintenance page ? Perfect, now let talk how to serve it.
Serve the maintenance page
The first component that receive the users requests should be serving the page. Depending your stack that means either the:
- HTTP server should serve the page
- HTTP reverse-proxy cache (aka. Varnish) should serve the page
In the first case i highly suggest you to make a dedicated maintenance VirtualHost
on a separate port.
In the second case you must modify your vcl_error
section with something like this:
if (obj.status == 703) {
set obj.status = 503;
set obj.http.Content-Type = "text/html; charset=utf-8";
synthetic {"
... Add HTML content here ...
"};
return(deliver);
}
Note the fake HTTP code 703
. We will use it later 😉
Maintain access for you, display maintenance page for others
If your maintenance page is served by Varnish use an acl
for IP filtering like this:
acl me_and_dev {
"1.2.3.4"/32;
}
sub vcl_recv {
if (!client.ip ~ me_and_dev) {
error 703 "Service unavailable";
}
}
If your maintenance page is served by Apache use an iptable rule to redirect traffic to the maintenance VirtualHost
‘s port except for your IP :
iptables -t NAT -A PREROUTING -i eth0 -p tcp --dport 80 \! -s '1.2.3.4' --to-ports 81
Note that if you can’t use IP filtering, other solution are possible like using a special maintenance cookie set after requesting a “secret url”.