Pro Tip: Redirecting to a Custom Nginx Maintenance Page
Here’s one I struggled with a bit while upgrading lincolnloop.com yesterday.
Scenario: You need to take your site offline and want to redirect all its traffic to a “down for maintenance” page. For search engine friendliness, that page should return a 503: Service Unavailable status code. Here’s the (not entirely intuitive) way to do that in Nginx:
server {
listen 80;
server_name mysite.com;
root /var/www/mysite.com/;
location / {
if (-f $document_root/maintenance.html) {
return 503;
}
... # the rest of your config goes here
}
error_page 503 @maintenance;
location @maintenance {
rewrite ^(.*)$ /maintenance.html break;
}
}
Now whenever you need to take your site offline, simply create the file maintenance.html in the $document_root (in our case, /var/www/mysite.com). If the file exists, Nginx will serve it with a 503 status code, if not, it will proceed as usual.
Comments
Got something to say?
Our Products
Categories
- accessiblity
- code
- company news
- django
- gondola
- open source
- portfolio
- presentation
- pro tip
- review
- screencast
- seo
- software
- subversion
- trailmapping
- wordpress
Archives
- July, 2010
- June, 2010
- May, 2010
- April, 2010
- February, 2010
- December, 2009
- November, 2009
- October, 2009
Elsewhere
What we’ve been up to online
-
I'll be trying to make dinner reservations for folks at #djangocon tonight. Restaurant recommendations in Portland?
Pete, 7 hours, 30 minutes ago -
forked divio/django-cms
Pete, 6 days, 9 hours ago -
Congrats on the new hires @eldarion_team ! Glad to see more growth in Django commercial services.
Pete, 1 week, 4 days ago -
Video: The amazing John Cleese shares his wisdom…
Pete, 1 week, 4 days ago -
Video: The amazing John Cleese shares his wisdom…
Pete, 1 week, 4 days ago -
@caktusgroup Congrats on the new hire! Great to see the growth of other Django development companies.
Pete, 3 weeks, 4 days ago -
Just launched a Flask/App Engine mini-site we've been tinkering on http://emailed-me.appspot.com/
Pete, 1 month, 1 week ago -
created repository Emailed-Me-
Pete, 1 month, 1 week ago -
Our first iPhone development project hit the App Store last week and is already over 1k users! Check them out @takemyspot #iphone #geodjango
Pete, 2 months ago -
Love the new sites! RT @welikesmall: We just launched two new sites. http://post.ly/mGoq
Pete, 2 months ago -
Pro tip: Using pip safely for automated deployment (no more pesky prompts) http://bit.ly/b5zsPa
Pete, 2 months, 1 week ago -
commented on justquick/django-mailfriend
Pete, 2 months, 1 week ago -
RT @unbracketed: Excited to have @mitsuhiko joining us for some work this summer :)
Pete, 2 months, 2 weeks ago -
New blog post: managing supervisord with upstart http://bit.ly/db3p5N
Pete, 2 months, 2 weeks ago -
Troubleshooting OpenID is just like user/password. Except you have 5 of them and and you don't know which one is failing, and 3 login pages
Pete, 2 months, 2 weeks ago


Thanks for the tip, I will be needing that soon.
Thank you for the code, helped. I have a small improvement tho: the 503 should be sent only to peoples who are not you, so that you can test the code on the server prior to remove the maintenance status. Also, you may want to server a pagee outsite of your site’s document root folder :).
geo $maintenance
{
default yes;
34.72.156.110 no; #your ip
}
server{
...
location / {
if ($maintenance = yes)
{
return 503;
}
…
error_page 503 502 @maintenance;
location @maintenance
{
root /usr/local/www/www.mysite.ro/_maintenance;
rewrite ^(.*)$ /index.html break;
}
}
Thank you!
My if (-f ..) is on the server level (outside of location) and for some reason when I did :
if (-f $document_root/maintenance.html) {
return 503;
}
it would return standard compiled in 503 error (which is ok), BUT mysteriously when I used custom 503 error page, as suggested by http://wiki.nginx.org/NginxHttpCoreModule#error_page, :
error_page 503 /503.html;
defined too on the server level, it would not return the contents of 503.html (or maintenance.html in your case) with the 503 error header, but just hit 10 redirect loops (error 500) and that was it. I tried a lot of variations (error_page before that if, error_page 503 = /503.html etc. etc.) and maybe 2 hours of trial/error.