When doing maintenance on a web application, you probably have a custom
503 site, showing your customers that the servers are currently lying on the operating table.
At the dynamic ridesharing service flinc, we touch a certian file on our reverse proxies (e.g. using capistrano
deploy:web:disable) when maintenance begins. Nginx then serves a static “we’ve disabled the site for maintenance” site, instead of the actual content.
But wouldn’t it be nice to test your web application before going live for your customers? It sure would. Unfortunately, this is not as simple as a task as you might think, because you cannot nest
if directives in an Nginx location and if is evil.
Because of hose limitations, we need another creative approach.
try_files is also forbidden in
if directives and only
rewrite are safe commands to use let’s abuse the unused HTTP status code
418 to work around this.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
Basically, as long as the
maintenance.html is not present or we are sitting in our office, we return the
418 status code. For customers, we’re serving
503 in case the site is disabled.
So let’s define the locations for normal operation (try serving the static files directly, and redirect all other requests to our upstream)
1 2 3 4 5 6 7
And finally, our maintenance site. We’re serving
maintenance.html instead of the requested site.
POST requests to static websites are not allowed and therefore all our disabled forms will return a
405 instead of the wanted
503, let’s correct those as well.
1 2 3 4 5 6 7 8 9
location directive makes sure that the static assets required for the maintenance page (images, stylesheets, etc) stored in
/maintenance are served normally.