[EN] Setting a custom maintenance page on nginx

I know we are living in the era of zero-downtime but, given my website user base and the fact that it’s really simple and small, I thought an old school “maintenance page” would be enough for me at the moment.

My deployment process is executed by a single command, so it’s quite stable and fast.

For the sake of completeness, I would talk a bit about my deployment process.

I use Fabric, so I have a few micro tasks in a Python script. Tasks like config_nginxconfig_monit,  etc.

I also have other bigger tasks that call those micro tasks in sequence, my two main tasks are config and deploy. I almost never use the config task, so… let’s talk about  what the deploy task does:

  • Set the settings configuration
  • Execute git pull
  • Activate the virtualenv
  • Install and upgrade the requirements packages with pip
  • Execute the Django migrations
  • Collect the static files
  • Compress the static files with django-compressor
  • Notify Opbeat about the new release

It’s really straight forward and simple to implement.

The maintenance mode

The following is a simplified version of my nginx configuration file:

server {
    listen 80;
    root /var/www/maintenance; [1]

    location / {
        if (-f $document_root/index.html) { [2]
            return 503;
        }
        # the rest of you configuration goes here
    }

    error_page 503 @maintenance; [3]
    location @maintenance { [4]
        rewrite ^(.*)$ /index.html break; [5]
    }
}

Let’s go to a basic definition of each point:

  1. Sets the root path for requests. I don’t use the root for any request, so I set it to a specific directory used for the maintenance mode.
  2. Check if there’s an index.html file in root directory. If the file exists I return the 503 Service Unavailable code.
  3. The error_page directive is used to specify the @maintenance location to be used to process the request.
  4. The @ prefix means this location is a named location, as such it’s not accessible by the client, being used only by other directives as error_page.
  5. Finally we simply serve the index.html document.

After altering the nginx configuration file for the website I created two other micro tasks in my Fabric script.

The first task simple copy the HTML document with an informative text about the maintenance process. This micro task is executed before every other task within the deploy task.

The other task is used to remove the index.html document, setting back the website to it’s normal functionality. This task is executed as the last process within that major deploy task.

Now, everytime I execute my deploy task the website is put into a maintenance mode and automatically pulled out from it.

I’ve also added the Google Analytics tracking code in this maintenance page. This way if the number of requests during the maintenance process consistently grow, I’ll start to focus on a zero-downtime deployment process.

I hope this could help you!

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