如何使用 Apache 和 mod_wsgi 托管 Django

利用 Apachemod_wsgi 在生产环境部署已经过充分测试。

mod_wsgi 是一个 Apache 模块,它可以管理任何 Python WSGI 应用,包括 Django。Django 支持所有支持 mod_wsgi 的 Apache 版本。

官方 mod_wsgi 文档 介绍了如何使用 mod_wsgi 的全部细节。你可能更喜欢从 安装和配置文档 开始。

基础配置

一旦你安装了 mod_wsgi 并且启用了它,请在你的Apache服务器的 httpd.conf 文件中添加如下内容。

WSGIScriptAlias / /path/to/mysite.com/mysite/wsgi.py
WSGIPythonHome /path/to/venv
WSGIPythonPath /path/to/mysite.com

<Directory /path/to/mysite.com/mysite>
<Files wsgi.py>
Require all granted
</Files>
</Directory>

WSGIScriptAlias 行的第一项是你所期望的应用所在的基础 URL 路径( / 根 url),第二项是 "WSGI 文件" 的位置——一般位于项目包之内(本例中是 mysite)。这告诉 Apache 用该文件中定义的 WSGI 应用响应指定 URL 下的请求。

如果你在某个 virtual environment 1 内为应用安装项目的 Python 依赖,将该 virtualenv 的路径添加至 WSGIPythonHome 。参考 mod_wsgi virtualenv guide 指南获取更多细节。

WSGIPythonPath 行确保你的项目包能从 Python path 导入;换句话说, import mysite 能正常工作。

1 片段确保 Apache 能访问文件 wsgi.py 文件。

下一步,我们需要确认 wsgi.py 文件包含一个 WSGI 应用对象。从 Django 1.4 起, startproject 会自动创建;换而言之,你无需手动创建。查阅 WSGI 概述文档 获取你需要配置的默认内容,以及其它可配置项。

警告

如果多个 Django 站点运行在同一 mod_wsgi 进程,它们会共用最先启动的站点配置。能通过以下修改改变行为:

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "{{ project_name }}.settings")

wsgi.py 中也这么改:

os.environ["DJANGO_SETTINGS_MODULE"] = "{{ project_name }}.settings"

或通过 使用 mod_wsgi 的后台模式 确保每个站点都运行于独立的后台进程。

为文件上传修复 UnicodeEncodeError

If you get a UnicodeEncodeError when uploading or writing files with file names or content that contains non-ASCII characters, make sure Apache is configured to support UTF-8 encoding:

export LANG='en_US.UTF-8'
export LC_ALL='en_US.UTF-8'

常见的配置文件路径是 /etc/apache2/envvars

Alternatively, if you are using mod_wsgi daemon mode you can add lang and locale options to the WSGIDaemonProcess directive:

WSGIDaemonProcess example.com lang='en_US.UTF-8' locale='en_US.UTF-8'

参考 Unicode 参考指引的 文件 章节获取细节信息。

使用 mod_wsgi 后台模式

"Daemon mode" 是运行 mod_wsgi 的推荐模式(在非 Windows 平台上)。为了创建必要的后台进程组并在其中运行 Django 实例,你需要添加合适的 WSGIDaemonProcessWSGIProcessGroup 指令。上述配置在你使用后台模式时需要点小修改,即你不能使用 WSGIPythonPath;作为替换,你要在 WSGIDaemonProcess 中添加 python-path 选项,例如:

WSGIDaemonProcess example.com python-home=/path/to/venv python-path=/path/to/mysite.com
WSGIProcessGroup example.com

如果你想在子目录中开放你的项目(本例中 https://example.com/mysite),你可在上述配置中添加 WSGIScriptAlias

WSGIScriptAlias /mysite /path/to/mysite.com/mysite/wsgi.py process-group=example.com

参考官方 mod_wsgi 文档获取 配置后台模式的细节

提供文件服务

Django doesn't serve files itself; it leaves that job to whichever web server you choose.

We recommend using a separate web server -- i.e., one that's not also running Django -- for serving media. Here are some good choices:

然而,若你别无选择,只能在与 Django 相同的 Apache VirtualHost 上提供媒体文件,你可以让 Apache 为一些 URL 提供静态媒体服务,其它的用 mod_wsgi 接口传递给 Django。

本例在站点根目录配置 Django,但以静态文件的形式提供 robots.txtfavicon.ico 以及 /static//media/ 中的内容。其它所有 URL 以 mod_wsgi 提供服务:

Alias /robots.txt /path/to/mysite.com/static/robots.txt
Alias /favicon.ico /path/to/mysite.com/static/favicon.ico

Alias /media/ /path/to/mysite.com/media/
Alias /static/ /path/to/mysite.com/static/

<Directory /path/to/mysite.com/static>
Require all granted
</Directory>

<Directory /path/to/mysite.com/media>
Require all granted
</Directory>

WSGIScriptAlias / /path/to/mysite.com/mysite/wsgi.py

<Directory /path/to/mysite.com/mysite>
<Files wsgi.py>
Require all granted
</Files>
</Directory>

服务后台文件

When django.contrib.staticfiles is in INSTALLED_APPS, the Django development server automatically serves the static files of the admin app (and any other installed apps). This is however not the case when you use any other server arrangement. You're responsible for setting up Apache, or whichever web server you're using, to serve the admin files.

后台文件位于 Django 发行版的 (django/contrib/admin/static/admin) 中。

We strongly recommend using django.contrib.staticfiles to handle the admin files (along with a web server as outlined in the previous section; this means using the collectstatic management command to collect the static files in STATIC_ROOT, and then configuring your web server to serve STATIC_ROOT at STATIC_URL), but here are three other approaches:

  1. 在文档根目录中创建一个指向后台静态文件的符号链接(Apache 配置中可能要添加 +FollowSymLinks)。
  2. 使用前文介绍的 Alias 指令,为合适的 URL (可能是 STATIC_URL + admin/) 取个别名,指向后台文件的实际位置。
  3. 直接将后台静态文件拷贝至 Apache 的文档根目录。

Apache 利用 Django 的用户数据库进行验证

Django 提供了一个处理器,允许 Apache 直接用 Django 的认证授权后端认证用户。参考文档 mod_wsgi 认证授权文档