Nginx maintenance page configuration with load-balancer health check

We wanted to add a maintenance page to our rails app running on nginx. Capistrano provides a simple task to show your maintenance page cap deploy:web:disable. It includes basic instructions for how to configure nginx, although I found these didn’t quite work for us as documented.

One thing the configuration suggests it to return a 503 status code so that crawlers know the site is temporarily down and will retry the crawl later. This made sense, but when we did this in front of the load balancer it automatically sent it’s own 503 to the browser because it detected that the app server was returning 503 (which is what it should do, or roll over to another server). What we needed was the ability to have our load balancer run it’s health check on the app server without getting the 503.

While I have read that that “If is evil” in nginx configurations, I found that I could check whether the request was the load balancer and return a 200 code within the maintenance handler:

        if ($request_filename ~ '/health_check') {
          return 200;
        }

I also learned a lot from this older post (like how to allow inclusion of graphic assets such as our logo). But the key trick was to put a bare ‘=’ on the error_pages line so that Nginx would return the handler’s response code, rather than 503 for all pages.

      error_page 503 = @maintenance;

Here is the entire configuration that we used (put this at the server level).

      recursive_error_pages on;
      
      if (-f $document_root/system/maintenance.html) {
        return 503;
      } 

      error_page 503 = @maintenance;
      location @maintenance {
        error_page 405 /system/maintenance.html;

        if ($request_filename ~ '/health_check') {
          return 200;
        }

        if (-f $request_filename) {
          break;
        }

        rewrite  ^(.*)$  /system/maintenance.html break;
      }
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s