We use a simple method of putting an Nginx site into maintenance mode. Just set a geo default variable on on and have it generate a HTTP 503 status response. Then Nginx delivers our maintenance page until we set it back to off

nginx.conf

geo $maintenance_SITE {
    default off;             # Set to 'on' to enable maintenance mode
    123.123.123.120/29 off;
}

upstream maintenance {
    server maint:80;
}

server {
  listen 443 ssl http2;
...
    if ($maintenance_SITE = on) {
        return 503;
    }

    error_page 503 @maintenance;

    location @maintenance {
        rewrite ^(.*)$ / break;
        proxy_pass http://maintenance;
    }
...
}

By using a geo I can add in our own ip addresses (the /29 range) so everyone but us, gets a 503 maintenance redirect. This way we can continue testing things as if the site were still live.

The next step is to get a script to tell me which sites are in what state and then progress to automating the set maintenance mode on and off.

Because I use a standard template for nginx files I can find the line that drives maintenance mode by looking for # Set to 'on' to enable maintenance mode. My script for telling me what the states are needs to grep the files in our nginx/conf.d folder for this and produce some output. This is what I came up with:

#!/bin/bash

# set -x

function get_state() {

    RESULTS=$(grep -E "# Set to 'on' to (enable|put into) maintenance mode" /etc/nginx/conf.d/*.conf)

    IFS=$'\n'
    for RESULT in ${RESULTS}; do
        SERIAL=$(echo ${RESULT} | sed -r -e "s/.*\/(.*)\.conf.*/\1/i")
        STATE=$(echo ${RESULT} | sed -r -e "s/.*default (off|on).*/\1/i")
        echo ${SERIAL} ${STATE}
    done

}

get_state

This produces just what I need to see, eg.

S00301 off
S00368 off
S00373 off

We use unique serial numbers to identify each site, but this would return the name of whatever .conf file matched the maintenance string with its current state. The maintenance_SITE also has the SERIAL as SITE so we don’t put all hosts into maintenance, just the ones we specify by serial number.