有什么方法可以用fabric将django站点置于维护模式?

8 投票
3 回答
10815 浏览
提问于 2025-04-16 19:20

我现在正在使用MaintenanceModeMiddleware来让我的网站进入维护模式,但这需要在远程服务器上的settings.py文件中进行更改。我想用fabric来远程让网站进入维护模式。有没有办法做到这一点?或者有没有更好的方法呢?谢谢。

[更新]

感谢大家的反馈,最后我做了这个,效果很好,http://garthhumphreys.com/2011/06/11/painless-django-maintenance-mode-with-fabric/ - 我喜欢取消注释的想法,但在我的设置中,如果我在生产服务器上这样做,一旦我推送新版本就会被覆盖。所以最终从服务器层面而不是django层面让网站进入维护模式效果更好,对我来说确实更简单灵活 :)

3 个回答

2

有一个叫做 django-maintenancemode 的项目的改版,它可以通过在数据库里设置一个值来开启或关闭维护模式。这样,你就可以创建一个简单的管理命令来切换维护模式,并通过 fabric 来调用它。我觉得这种方法比使用 mod_rewrite 更灵活。

4

我的解决方案:

  1. 首先,创建一个维护模式的模板,并通过一个网址链接到它,这样当你访问 /under-maintenance/ 时,就会显示一个维护页面。
  2. 接着,配置Apache服务器,让它检查是否存在一个名为 'maintenance-mode-on' 的文件,如果这个文件存在,就把访问者重定向到维护页面的地址。
  3. 然后,配置Apache服务器,让它在检测到 'maintenance-mode-off' 文件存在时,从维护模式的地址重定向回主页。
  4. 使用Fabric脚本来方便地在 'maintenance-mode-on' 和 'maintenance-mode-off' 文件之间切换。

以下是Apache配置文件中相关的部分:

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]

然后是Fabric脚本中相关的部分:

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!')

这个方法效果不错,不过它依赖于Django在维护模式下处理请求;如果能直接提供一个静态文件就更好了。

9

Fabric确实有一些命令,可以帮助你在指定的文件中添加或去掉注释,这些命令在fabric.contrib.files里。你可以查看这里的文档了解更多信息:http://docs.fabfile.org/en/1.0.1/api/contrib/files.html

就我个人而言,我更喜欢在前端代理处理这个问题,而不是在Django的中间件里。我建议你看看这个问题:当上游服务不可用时显示自定义的503页面,这个问题讲的是如何配置Nginx在上游服务不可用时使用自定义页面。

撰写回答