Is there anyway to put a django site into maintenance mode using fabric?
I'm currently using MaintenanceModeMiddleware to put my site into maintenance mode, but it requires you make the change in the settings.py file on the remote server. I would like to use fabric to remotely put the site into maintenance mode. Is there a way to achieve this? Or is there a better method for doing this? 开发者_运维问答Thanks.
[UPDATE]
Thanks for the feedback everyone in the end this is what I did and it works great for me, http://garthhumphreys.com/2011/06/11/painless-django-maintenance-mode-with-fabric/ - I do like the idea of uncomment lines but with my setup if I were to do that on the production server it would be overwritten once I pushed the new version out, so in the end putting the site into maintenance mode from the server level and not the django level works a lot better and is truly easier and flexible, for me at least :)
Fabric does have commands to help you comment or uncomment lines in a given file in fabric.contrib.files
. See the docs here: http://docs.fabfile.org/en/1.0.1/api/contrib/files.html
Personally I prefer to handle this at the front-end proxy rather than in a Django middleware. I would take a look at this question Show a custom 503 page if upstream is down which configures Nginx to use a custom page when the upstream is down.
My solution:
- Create a maintenance mode template and link to it via a urlconf, so when visiting /under-maintenance/ a maintenance page is shown.
- Then, configure apache to test for the presence of a 'maintenance-mode-on' file, and if it is present do a 302 redirect to the url of the maintenance mode page.
- Configure apache to redirect from the maintenance mode URL to the home page, if the 'maintenance-mode-off' file is present.
- Fabric script to facilitate switching the files between maintenance-mode-on and maintenance-mode-off.
Here's the relevant section of the Apache config file:
RewriteEngine On
# If this file (toggle file) exists then put the site into maintenance mode
RewriteCond /path/to/toggle/file/maintenance-mode-on -f
RewriteCond %{REQUEST_URI} !^/static.*
RewriteCond %{REQUEST_URI} !^/admin.*
RewriteCond %{REQUEST_URI} !^/under-maintenance/
# redirect to the maintenance mode page
RewriteRule ^(.*) /under-maintenance/ [R,L]
#If not under maintenance mode, redirect away from the maintenance page
RewriteCond /path/to/toggle/file/maintenance-mode-off -f
RewriteCond %{REQUEST_URI} ^/under-maintenance/
RewriteRule ^(.*) / [R,L]
Then the relevant parts of the fabric script:
env.var_dir = '/path/to/toggle/file/'
def is_in_mm():
"Returns whether the site is in maintenance mode"
return files.exists(os.path.join(env.var_dir, 'maintenance-mode-on'))
@task
def mm_on():
"""Turns on maintenance mode"""
if not is_in_mm():
with cd(env.var_dir):
run('mv maintenance-mode-off maintenance-mode-on')
utils.fastprint('Turned on maintenance mode.')
else:
utils.error('The site is already in maintenance mode!')
@task
def mm_off():
"""Turns off maintenance mode"""
if is_in_mm():
with cd(env.var_dir):
run('mv maintenance-mode-on maintenance-mode-off')
utils.fastprint('Turned off maintenance mode.')
else:
utils.error('The site is not in maintenance mode!')
This works well, though it does depend on Django handling requests during maintenance mode; it would be nice to just serve a static file.
There is a fork of django-maintenancemode that allows to turn the maintenance mode on/off by setting a value in database. This way you can, for example, create a simple management command to toggle the maintenance mode and call it via fabric. I think it's more flexible than using mod_rewrite.
精彩评论