部署清单

互联网是一个恶劣的环境。在部署你的 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()

If rotating secret keys, you may use SECRET_KEY_FALLBACKS:

import os

SECRET_KEY = os.environ["CURRENT_SECRET_KEY"]
SECRET_KEY_FALLBACKS = [
    os.environ["OLD_SECRET_KEY"],
]

Ensure that old secret keys are removed from SECRET_KEY_FALLBACKS in a timely manner.

DEBUG

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

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

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

特定于环境的配置

ALLOWED_HOSTS

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

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

你还应该配置位于 Django 前面的网络服务器来验证主机。它应该用一个静态错误页面来回应,或者忽略不正确主机的请求,而不是将请求转发给 Django。这样你就可以避免在你的 Django 日志中出现虚假的错误(如果你有配置错误报告的话,也可以用电子邮件)。例如,在 nginx 上,你可以设置一个默认的服务器,在一个未识别的主机上返回“444 No Response”。

server {
    listen 80 default_server;
    return 444;
}

CACHES

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

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

DATABASES

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

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

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

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

STATIC_ROOTSTATIC_URL

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

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

MEDIA_ROOTMEDIA_URL

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

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

HTTPS

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

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

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

性能优化

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

会话

建议参考 cached sessions 1 以提升性能。

如果使用数据库来备份会话,参考 clear old sessions 1 以避免存储不必要的数据。

CONN_MAX_AGE

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

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

TEMPLATES

Enabling the cached template loader often improves performance drastically, as it avoids compiling each template every time it needs to be rendered. When DEBUG = False, the cached template loader is enabled automatically. See django.template.loaders.cached.Loader for more information.

发送错误

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

LOGGING

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

查看 日志 了解 logging 的细节。

ADMINSMANAGERS

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

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

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

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

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

自定义默认错误视图

Django 包括几个 HTTP 错误代码的默认视图和模板。你可能想覆盖默认模板,在你的根模板目录下创建以下模板:404.html500.html403.html400.html。使用这些模板的 默认错误视图 应该足以满足 99% 的网络应用,但你也可以 自定义它们