Painless Django maintenance mode with Fabric

I wanted to share this process that I’ve figured out since I couldn’t find a solid answer anywhere online, I hope it helps someone and saves them time and headaches. The problem, “How to put your Django site into maintenance mode” –  the easy way with Fabric.

Truth be told I figured this out by combining info from How to use mod_rewrite rules to easily enable web site “maintenance” modes by Meitar Moscovitz this article pointed me in the right direction.

So here is the solution for using Fabric to put your Django site into maintenance mode;

1. First make sure you create a empty file on your server, this will be your toggle file (or at least this is what I call it). We’ll use this to check whether or not the maintenance mode is on or off.

In this case I created a file called “maintenance-mode-on” and put it in on my server that’s serving the static content for my Django site.

2. In your .htaccess or httpd.conf file add this,

RewriteEngine On
# If this file (toggle file) exsists then put the site into maintenance mode
RewriteCond /path/to/where/your/toggle/file/is/located/on/the/server -f
# If coming from approved ip address, then don't put it into maintenance mode,
# here I'm using HTTP:x-forwarded-for in place of REMOTE_ADDR this is because some users (or your yourself) might
# arrive to the site via a proxy server, so it's more accurate to use HTTP:x-forwarded-for to get the real ip address,
# Also please note that the ip address below has '\' in them because HTTP:x-forwarded-for returns or stores the ip address as a comma delimited list
RewriteCond %{HTTP:x-forwarded-for} !^127\.127\.127\.127$
# redirect to the maintenance mode page
RewriteRule ^(.+) /path/to/the/maintenance/mode/directory/or/index.html/$1 [L]

3. Once that’s done you can now create two new Fabric commands;

# One for renaming the toggle file from 'maintenance-mode-off' to 'maintenance-mode-on', this will turn on the maintenance mode the next time someone refreshes the page or clicks on a link
def mm_on():
with cd('~/path/to/where/your/toggle/file/is/located/on/the/server'):
run('mv maintenance-mode-off maintenance-mode-on')
# And this command turns the maintenance mode off, again by renaming the "toggle file".
def mm_off():
with cd('~/path/to/where/your/toggle/file/is/located/on/the/server'):
run('mv maintenance-mode-on maintenance-mode-off')

And presto that’s it, you can now put your site into maintenance mode, make the necessary changes and database backups or whatever, without having to worry that users are still in or on the site.