logo

"I've got something to say."

And it might even be worth listening to.
I hope you enjoy these personal and professional ruminations on life, living, and making a living as a web developer.
Maintenance Mode for Django Sites
E-mail

Wouldn’t it be handy to easily put a Django-driven site into “maintenance” mode – redirecting all site traffic to a “we’ll be back soon” page – while you still have access to the site, admin and all?

Well, you can.

django-maintenancemode is “a middleware that allows you to temporary shutdown your site for maintenance work.”

When activated, this middleware adds a 503handler, which looks for a 503.html page in your main templates directory and redirects site traffic to that page. But:

“Logged in users having staff credentials can still fully use the site as can users visiting the site from an IP address defined in Django's INTERNAL_IPS.”

(A side note: Django’s INTERNAL_IPS are also used to determine who sees the full Django debug info when site debugging is turned on. So maintenancemode is not the only thing using it.)

So I downloaded and installed the package according to instructions, uploaded a 503.html to my templates directory, modified my Django settings.py file as instructed, and…

Nothing. I was still seeing the “normal” site, not the 503 “maintenance” page. What’s up?

Remember, if maintenancemode finds your IP address in the site’s INTERNAL_IPS tuple, it will give you normal access to the site. A nice feature, but my IP address wasn’t in INTERNAL_IPS. Not good.

Maintenancemode will also give you normal site access if you had previously logged  into the site (before turning maintenancemode on) AND you have “staff” status in the admin tool. But I wasn’t logged in. Strike two.

I finally added send_mail() to the MaintenanceModeMiddleware class to email myself a copy of exactly what was being passed to that class.

Remember the INTERNAL_IPS tuple? One of the addresses set in my client’s site was 127.0.0.1. Oddly my IP’s REMOTE_ADDRESS was being interpreted as 127.0.0.1 (and obviously, it isn’t)! So maintenancemode was giving me full access to the site because it thought my IP address is 127.0.0.1 and that was one of its “let ‘em through” IP’s.

I could just have removed 127.0.0.1 from INTERNAL_IPS and be done with it. But why in the world was my REMOTE_ADDRESS being interpreted as 127.0.0.1? I have to get that fixed…

After a note to the support desk of my client’s web host, all became clear: the server was using squid to serve up static content (rather than place the burden on Django) and all incoming requests come to squid first and then are passed on to Apache/Django as coming from 127.0.0.1!

Squid does put the original requesting IP address into the X-Forwarded-For http header, so support simply dropped the HTTP_X_FORWARDED_FOR var into REMOTE_ADDR, and all was well again.

I hope this will save a couple of hours of frustration for someone else, and maybe it wil redeem the couple of hours I spent scratching my head and needlessly mumbling under my breath about a great little tool called maintenancemode!