部署清单

互联网是一个恶劣的环境。在部署你的 Django 项目之前,你应该将安全、性能和操作铭记于心,并花一些时间来检查你的配置。

Django 包含了许多 安全特性。一些是内置的并且总保持激活状态,其他的则是可选的因为它们不总是恰当的,或者因为它们不便于之后的开发。举个例子,强制的 HTTPS 并不一定适合所有网站,它对于本地开发就是不切实际的。

性能优化是另一项便利性权衡的主题。例如,缓存在生成环境很有用,但是对本地开发就作用不大。错误报告的需求也大不相同。

以下清单包括以下配置:

  • 必须正确地设置 Django 以提供预期的安全级别;
  • 期望在每个环境中都是不同的;
  • 启用可选的安全功能;
  • 启用性能优化;
  • 提供错误报告功能。

许多配置项是敏感的,需要被当做机密对待。如果要发布项目源码,常见操作是为开发开放合适的配置项,为生产环境配置私密设置模块。

运行 manage.py check --deploy

下面介绍的某些检查项会自动使用 check --deploy 选项。请确保根据选项文档中描述的生产设置文件运行它。

关键配置

SECRET_KEY

密码必须是一个较长的随机值,且被妥善保存。

确保生产环境使用的密码并未用于其它环境,且未被提交至版本控制系统。这将减少攻击者获取密码的概率。

逾期将安全密码硬编码在配置模块中,不然考虑从环境变量加载它:

import os
SECRET_KEY = os.environ['SECRET_KEY']

或者从一个文件:

with open('/etc/secret_key.txt') as f:
    SECRET_KEY = f.read().strip()

DEBUG

永远不要在生产环境打开 debug 开关。

开发时,你当然要配置 DEBUG = True,这将方便你在浏览器启用完全回溯功能。

不过,对于生产环境来说,这真是一个坏主意,因为这会泄露很多超出预期的信息:代码摘要,本地变量,配置项,使用的库,等等。

特定于环境的配置

ALLOWED_HOSTS

DEBUG = False 时,Django 在未正确配置 ALLOWED_HOSTS 时无法工作。

该配置避免你的站点遭受某些 CSRF 攻击。如果使用了通配符,你必须实现自定义的 Host HTTP 头,或者确保你不会很容易地遭受此种攻击。

你也需要配置挡在 Django 之前的 Web 服务器,让它验证主机。它应该忽略来自错误主机的请求,或返回静态错误页,而不是将请求重定向至 Django。这样做能避免 Django 日志中出现虚假错误(或在配置此种错误后,避免发送错误报告邮件)。例如,在 nginx 上,你可能配置了一个默认主机,为未识别的主机返回 “444 No Response”:

server {
    listen 80 default_server;
    return 444;
}

CACHES

若使用了缓存,开发环境的连接参数和生产环境可能不同。Djano 默认为每个进程提供 本地内存缓存,这可能与期望不同。

缓存服务器一般采用若验证。确保它们只接受来自你的应用服务器的连接。

若你使用了 Memcached,考虑用 缓存会话 来提高性能。

DATABASES

生产环境与开发环境的数据库连接参数可能是不同的。

数据库密码是机密的。你应该像保护 SECRET_KEY 那样保护它们。

为了最大限度的安全,确保数据库只为来自你应用的连接提供服务。

如果你还未为数据库设置备份,现在就做!

STATIC_ROOTSTATIC_URL

静态文件由开发服务器自动托管。但在生产环境,你必须定义配置 STATIC_ROOTcollectstatic 将会拷贝它们。

查看 管理静态文件(比如图片、JavaScript、CSS) 获得更多信息。

MEDIA_ROOTMEDIA_URL

媒体文件由用户上传。他们是不可信任的!确保 web 服务器从未尝试解析这些文件。例如,若用户上传了一个 .php 文件,web 服务器应该永远不要运行它。

现在是检查这些文件的备份策略的好时机。

FILE_UPLOAD_PERMISSIONS

默认文件上传配置下,大小小于 FILE_UPLOAD_MAX_MEMORY_SIZE 的文件可能与 FILE_UPLOAD_PERMISSIONS 中描述的大文件的存储模式不同。

配置项 FILE_UPLOAD_PERMISSIONS 确保了所有的文件均已相同的权限上传。

HTTPS

允许用户登录的网站应该强制站点范围的 HTTPS,避免明文传输令牌。在 Django 中,令牌包括账号/密码,会话 cookie 和重置密码的令牌。(如果你用邮件发送重置密码的令牌,那就没什么办法能保护它们。)

仅保护用户账号或后台等敏感区域是不够的,因为 HTTP 和 HTTPS 使用相同的会话 cookie。Web 服务器必须将所有的 HTTP 重定向至 HTTPS,且只将 HTTPS 的请求转发给 Django。

若你已经配置了 HTTPS,启用下列配置。

性能优化

配置 DEBUG = False 会禁用几个仅在开发时有用的功能。另外,你要调整下列配置。

CONN_MAX_AGE

开启 持久数据库连接 会在连接数据库账号耗费了请求处理时间的很大一部分的时候,大大提升速度。

这对带宽有限的虚拟主机帮助极大。

TEMPLATES

启用缓存的模板加载器通常会极大地提升性能,因为它避免了每次渲染模板时都编译它们。参考 模板加载器文档 获取更多信息。

发送错误

在你将代码推送至生产环境后,你总是期望代码是健壮的,但你并不能控制意料之外的错误。还好,Django 能捕获错误并通知你。

LOGGING

在将网站放入生产环境前,检查 logging 配置项。在你收到某些信息后,查看其是否按预期运行。

查看 日志 了解 logging 的细节。

ADMINSMANAGERS

发生 500 错误时,会邮件通知 ADMINS

404 错误会通知 MANAGERSIGNORABLE_404_URLS 有助于过滤误报。

参考 发送错误 了解邮件如何在发生错误时发送报告的细节。

利用邮件报告错误的弹性并不好

在收件箱被报告塞满前,考虑下使用错误监控系统,类似 Sentry。Sentry 还可以聚合日志。

自定义默认错误视图

Django 为好几个 HTTP 错误代码提供了默认的视图和模板。你能通过在根模板目录创建下列模板文件的方式重写默认模板: 404.html500.html403.html400.html。 使用这些模板的 默认错误视图 能满足 99% 的 Web 应用,不过你也能 自定义它们