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.
精彩评论