{"title":"如何使用 Apache 和 mod_wsgi 托管 Django","version":"3.1","locale":"zh-hans","docname":"howto/deployment/wsgi/modwsgi","url":"/zh-hans/3.1/howto/deployment/wsgi/modwsgi/","canonical":"https://djangodocs.dev/zh-hans/3.1/howto/deployment/wsgi/modwsgi/","summary":"利用 Apache 和 mod_wsgi 在生产环境部署已经过充分测试。 mod_wsgi 是一个 Apache 模块，它可以管理任何 Python WSGI 应用，包括 Django。Django 支持所有支持 mod_wsgi 的 Apache 版本。 官方 mod_wsgi 文档 介绍了如何使用 mod_wsgi…","html":"<h1>如何使用 Apache 和 <code class=\"docutils literal notranslate\"><span class=\"pre\">mod_wsgi</span></code> 托管 Django<a class=\"heading-anchor\" href=\"#how-to-use-django-with-apache-and-mod-wsgi\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>利用 <a class=\"reference external\" href=\"https://httpd.apache.org/\">Apache</a> 和 <a class=\"reference external\" href=\"https://modwsgi.readthedocs.io/en/develop/\">mod_wsgi</a> 在生产环境部署已经过充分测试。</p>\n<p>mod_wsgi 是一个 Apache 模块，它可以管理任何 Python <a class=\"reference external\" href=\"https://wsgi.readthedocs.io/en/latest/\">WSGI</a> 应用，包括 Django。Django 支持所有支持 mod_wsgi 的 Apache 版本。</p>\n<p><a class=\"reference external\" href=\"https://modwsgi.readthedocs.io/en/develop/installation.html\">官方 mod_wsgi 文档</a> 介绍了如何使用 mod_wsgi 的全部细节。你可能更喜欢从 <a class=\"reference external\" href=\"https://modwsgi.readthedocs.io/\">安装和配置文档</a> 开始。</p>\n<section id=\"basic-configuration\">\n<h2>基础配置<a class=\"heading-anchor\" href=\"#basic-configuration\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>一旦你安装了 mod_wsgi 并且启用了它，请在你的Apache服务器的 <a class=\"reference external\" href=\"https://wiki.apache.org/httpd/DistrosDefaultLayout\">httpd.conf</a> 文件中添加如下内容。</p>\n<div class=\"code-block\" data-language=\"apache\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Apache</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Apache code\"><code><span class=\"nb\">WSGIScriptAlias</span><span class=\"w\"> </span>/<span class=\"w\"> </span><span class=\"sx\">/path/to/mysite.com/mysite/wsgi.py</span>\n<span class=\"nb\">WSGIPythonHome</span><span class=\"w\"> </span><span class=\"sx\">/path/to/venv</span>\n<span class=\"nb\">WSGIPythonPath</span><span class=\"w\"> </span><span class=\"sx\">/path/to/mysite.com</span>\n\n<span class=\"nt\">&lt;Directory</span><span class=\"w\"> </span><span class=\"s\">/path/to/mysite.com/mysite</span><span class=\"nt\">&gt;</span>\n<span class=\"nt\">&lt;Files</span><span class=\"w\"> </span><span class=\"s\">wsgi.py</span><span class=\"nt\">&gt;</span>\n<span class=\"nb\">Require</span><span class=\"w\"> </span><span class=\"k\">all</span><span class=\"w\"> </span>granted\n<span class=\"nt\">&lt;/Files&gt;</span>\n<span class=\"nt\">&lt;/Directory&gt;</span>\n</code></pre></div>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">WSGIScriptAlias</span></code> 行的第一项是你所期望的应用所在的基础 URL 路径（ <code class=\"docutils literal notranslate\"><span class=\"pre\">/</span></code> 根 url），第二项是 &quot;WSGI 文件&quot; 的位置——一般位于项目包之内（本例中是 <code class=\"docutils literal notranslate\"><span class=\"pre\">mysite</span></code>）。这告诉 Apache 用该文件中定义的 WSGI 应用响应指定 URL 下的请求。</p>\n<p>如果你在某个 <code class=\"xref py py-mod docutils literal notranslate\"><span class=\"pre\">virtual</span> <span class=\"pre\">environment</span> <span class=\"pre\">1</span></code> 内为应用安装项目的 Python 依赖，将该 virtualenv 的路径添加至 <code class=\"docutils literal notranslate\"><span class=\"pre\">WSGIPythonHome</span></code> 。参考 <a class=\"reference external\" href=\"https://modwsgi.readthedocs.io/en/develop/user-guides/virtual-environments.html\">mod_wsgi virtualenv guide</a> 指南获取更多细节。</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">WSGIPythonPath</span></code> 行确保你的项目包能从 Python path 导入；换句话说， <code class=\"docutils literal notranslate\"><span class=\"pre\">import</span> <span class=\"pre\">mysite</span></code> 能正常工作。</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">1</span></code> 片段确保 Apache 能访问文件 <code class=\"file docutils literal notranslate\"><span class=\"pre\">wsgi.py</span></code> 文件。</p>\n<p>下一步，我们需要确认 <code class=\"file docutils literal notranslate\"><span class=\"pre\">wsgi.py</span></code> 文件包含一个 WSGI 应用对象。从 Django 1.4 起， <a class=\"reference internal\" href=\"/zh-hans/3.1/ref/django-admin/#django-admin-startproject\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">startproject</span></code></a> 会自动创建；换而言之，你无需手动创建。查阅 <a class=\"reference internal\" href=\"/zh-hans/3.1/howto/deployment/wsgi/\"><span class=\"doc\">WSGI 概述文档</span></a> 获取你需要配置的默认内容，以及其它可配置项。</p>\n<aside class=\"admonition admonition-warning\" role=\"note\">\n<p class=\"admonition-title\">Warning</p>\n<p>如果多个 Django 站点运行在同一 mod_wsgi 进程，它们会共用最先启动的站点配置。能通过以下修改改变行为:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">environ</span><span class=\"o\">.</span><span class=\"n\">setdefault</span><span class=\"p\">(</span><span class=\"s2\">&quot;DJANGO_SETTINGS_MODULE&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;{{ project_name }}.settings&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">wsgi.py</span></code> 中也这么改:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">environ</span><span class=\"p\">[</span><span class=\"s2\">&quot;DJANGO_SETTINGS_MODULE&quot;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;{{ project_name }}.settings&quot;</span>\n</code></pre></div>\n<p>或通过 <a class=\"reference internal\" href=\"#daemon-mode\"><span class=\"std std-ref\">使用 mod_wsgi 的后台模式</span></a> 确保每个站点都运行于独立的后台进程。</p>\n</aside>\n<aside class=\"admonition-fixing-unicodeencodeerror-for-file-uploads admonition\">\n<p class=\"admonition-title\">为文件上传修复 <code class=\"docutils literal notranslate\"><span class=\"pre\">UnicodeEncodeError</span></code></p>\n<p>上传名称包含非 ASCII 字符的文件时，若抛出 <code class=\"docutils literal notranslate\"><span class=\"pre\">UnicodeEncodeError</span></code>，确认 Apache 是否被正确配置，能接受非 ASCII 文件名:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"n\">export</span> <span class=\"n\">LANG</span><span class=\"o\">=</span><span class=\"s1\">&#39;en_US.UTF-8&#39;</span>\n<span class=\"n\">export</span> <span class=\"n\">LC_ALL</span><span class=\"o\">=</span><span class=\"s1\">&#39;en_US.UTF-8&#39;</span>\n</code></pre></div>\n<p>常见的配置文件路径是 <code class=\"docutils literal notranslate\"><span class=\"pre\">/etc/apache2/envvars</span></code>。</p>\n<p>参考 Unicode 参考指引的 <a class=\"reference internal\" href=\"/zh-hans/3.1/ref/unicode/#unicode-files\"><span class=\"std std-ref\">文件</span></a> 章节获取细节信息。</p>\n</aside>\n</section>\n<section id=\"using-mod-wsgi-daemon-mode\">\n<span id=\"daemon-mode\"></span><h2>使用 <code class=\"docutils literal notranslate\"><span class=\"pre\">mod_wsgi</span></code> 后台模式<a class=\"heading-anchor\" href=\"#using-mod-wsgi-daemon-mode\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>&quot;Daemon mode&quot; 是运行 mod_wsgi 的推荐模式（在非 Windows 平台上）。为了创建必要的后台进程组并在其中运行 Django 实例，你需要添加合适的 <code class=\"docutils literal notranslate\"><span class=\"pre\">WSGIDaemonProcess</span></code> 和 <code class=\"docutils literal notranslate\"><span class=\"pre\">WSGIProcessGroup</span></code> 指令。上述配置在你使用后台模式时需要点小修改，即你不能使用 <code class=\"docutils literal notranslate\"><span class=\"pre\">WSGIPythonPath</span></code>；作为替换，你要在 <code class=\"docutils literal notranslate\"><span class=\"pre\">WSGIDaemonProcess</span></code> 中添加 <code class=\"docutils literal notranslate\"><span class=\"pre\">python-path</span></code> 选项，例如：</p>\n<div class=\"code-block\" data-language=\"apache\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Apache</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Apache code\"><code><span class=\"nb\">WSGIDaemonProcess</span><span class=\"w\"> </span>example.com<span class=\"w\"> </span>python-home=/path/to/venv<span class=\"w\"> </span>python-path=/path/to/mysite.com\n<span class=\"nb\">WSGIProcessGroup</span><span class=\"w\"> </span>example.com\n</code></pre></div>\n<p>如果你想在子目录中开放你的项目（本例中 <code class=\"docutils literal notranslate\"><span class=\"pre\">https://example.com/mysite</span></code>），你可在上述配置中添加 <code class=\"docutils literal notranslate\"><span class=\"pre\">WSGIScriptAlias</span></code>：</p>\n<div class=\"code-block\" data-language=\"apache\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Apache</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Apache code\"><code><span class=\"nb\">WSGIScriptAlias</span><span class=\"w\"> </span><span class=\"sx\">/mysite</span><span class=\"w\"> </span><span class=\"sx\">/path/to/mysite.com/mysite/wsgi.py</span><span class=\"w\"> </span>process-group=example.com\n</code></pre></div>\n<p>参考官方 mod_wsgi 文档获取 <a class=\"reference external\" href=\"https://modwsgi.readthedocs.io/en/develop/user-guides/quick-configuration-guide.html#delegation-to-daemon-process\">配置后台模式的细节</a>。</p>\n</section>\n<section id=\"serving-files\">\n<span id=\"id1\"></span><h2>提供文件服务<a class=\"heading-anchor\" href=\"#serving-files\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Django 本身并不提供文件服务；他将这个职责交给了你选择的 Web 服务器。</p>\n<p>我们推荐使用一个独立的 Web 服务器，即其未运行 Django——仅用于媒体服务。以下是一些不错的选项：</p>\n<ul class=\"simple\">\n<li><p><a class=\"reference external\" href=\"https://nginx.org/en/\">Nginx</a></p></li>\n<li><p>一个 <a class=\"reference external\" href=\"https://httpd.apache.org/\">Apache</a> 的朴素版本</p></li>\n</ul>\n<p>然而，若你别无选择，只能在与 Django 相同的 Apache <code class=\"docutils literal notranslate\"><span class=\"pre\">VirtualHost</span></code> 上提供媒体文件，你可以让 Apache 为一些 URL 提供静态媒体服务，其它的用 mod_wsgi 接口传递给 Django。</p>\n<p>本例在站点根目录配置 Django，但以静态文件的形式提供 <code class=\"docutils literal notranslate\"><span class=\"pre\">robots.txt</span></code>， <code class=\"docutils literal notranslate\"><span class=\"pre\">favicon.ico</span></code> 以及 <code class=\"docutils literal notranslate\"><span class=\"pre\">/static/</span></code> 和 <code class=\"docutils literal notranslate\"><span class=\"pre\">/media/</span></code> 中的内容。其它所有 URL 以 mod_wsgi 提供服务：</p>\n<div class=\"code-block\" data-language=\"apache\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Apache</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Apache code\"><code><span class=\"nb\">Alias</span><span class=\"w\"> </span><span class=\"sx\">/robots.txt</span><span class=\"w\"> </span><span class=\"sx\">/path/to/mysite.com/static/robots.txt</span>\n<span class=\"nb\">Alias</span><span class=\"w\"> </span><span class=\"sx\">/favicon.ico</span><span class=\"w\"> </span><span class=\"sx\">/path/to/mysite.com/static/favicon.ico</span>\n\n<span class=\"nb\">Alias</span><span class=\"w\"> </span><span class=\"sx\">/media/</span><span class=\"w\"> </span><span class=\"sx\">/path/to/mysite.com/media/</span>\n<span class=\"nb\">Alias</span><span class=\"w\"> </span><span class=\"sx\">/static/</span><span class=\"w\"> </span><span class=\"sx\">/path/to/mysite.com/static/</span>\n\n<span class=\"nt\">&lt;Directory</span><span class=\"w\"> </span><span class=\"s\">/path/to/mysite.com/static</span><span class=\"nt\">&gt;</span>\n<span class=\"nb\">Require</span><span class=\"w\"> </span><span class=\"k\">all</span><span class=\"w\"> </span>granted\n<span class=\"nt\">&lt;/Directory&gt;</span>\n\n<span class=\"nt\">&lt;Directory</span><span class=\"w\"> </span><span class=\"s\">/path/to/mysite.com/media</span><span class=\"nt\">&gt;</span>\n<span class=\"nb\">Require</span><span class=\"w\"> </span><span class=\"k\">all</span><span class=\"w\"> </span>granted\n<span class=\"nt\">&lt;/Directory&gt;</span>\n\n<span class=\"nb\">WSGIScriptAlias</span><span class=\"w\"> </span>/<span class=\"w\"> </span><span class=\"sx\">/path/to/mysite.com/mysite/wsgi.py</span>\n\n<span class=\"nt\">&lt;Directory</span><span class=\"w\"> </span><span class=\"s\">/path/to/mysite.com/mysite</span><span class=\"nt\">&gt;</span>\n<span class=\"nt\">&lt;Files</span><span class=\"w\"> </span><span class=\"s\">wsgi.py</span><span class=\"nt\">&gt;</span>\n<span class=\"nb\">Require</span><span class=\"w\"> </span><span class=\"k\">all</span><span class=\"w\"> </span>granted\n<span class=\"nt\">&lt;/Files&gt;</span>\n<span class=\"nt\">&lt;/Directory&gt;</span>\n</code></pre></div>\n</section>\n<section id=\"serving-the-admin-files\">\n<span id=\"id3\"></span><h2>服务后台文件<a class=\"heading-anchor\" href=\"#serving-the-admin-files\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p><a class=\"reference internal\" href=\"/zh-hans/3.1/ref/settings/#std-setting-INSTALLED_APPS\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">INSTALLED_APPS</span></code></a> 中包含 <a class=\"reference internal\" href=\"/zh-hans/3.1/ref/contrib/staticfiles/#module-django.contrib.staticfiles\" title=\"django.contrib.staticfiles: An app for handling static files.\"><code class=\"xref py py-mod docutils literal notranslate\"><span class=\"pre\">django.contrib.staticfiles</span></code></a> 时，Django 开发服务器自动为这些归属于后台应用（也包含其它已安装的应用）的静态文件提供服务。这与你使用其它服务器时不太一样。你需要正确配置 Apache 或其它你使用的 Web 服务器，另其正确的为后台文件提供服务。</p>\n<p>后台文件位于 Django 发行版的 (<code class=\"file docutils literal notranslate\"><span class=\"pre\">django/contrib/admin/static/admin</span></code>) 中。</p>\n<p>我们 <strong>强烈</strong> 建议用 <a class=\"reference internal\" href=\"/zh-hans/3.1/ref/contrib/staticfiles/#module-django.contrib.staticfiles\" title=\"django.contrib.staticfiles: An app for handling static files.\"><code class=\"xref py py-mod docutils literal notranslate\"><span class=\"pre\">django.contrib.staticfiles</span></code></a> 处理后台文件（连同上一节所述的 Web 服务器；这意味着用 <a class=\"reference internal\" href=\"/zh-hans/3.1/ref/contrib/staticfiles/#django-admin-collectstatic\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">collectstatic</span></code></a> 管理命令收集 <a class=\"reference internal\" href=\"/zh-hans/3.1/ref/settings/#std-setting-STATIC_ROOT\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">STATIC_ROOT</span></code></a> 中的静态文件，然后配置 Web 服务器，使其在 <a class=\"reference internal\" href=\"/zh-hans/3.1/ref/settings/#std-setting-STATIC_URL\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">STATIC_URL</span></code></a> 为 <a class=\"reference internal\" href=\"/zh-hans/3.1/ref/settings/#std-setting-STATIC_ROOT\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">STATIC_ROOT</span></code></a> 提供服务），不过，这还有几个方法：</p>\n<ol class=\"arabic simple\">\n<li><p>在文档根目录中创建一个指向后台静态文件的符号链接（Apache 配置中可能要添加 <code class=\"docutils literal notranslate\"><span class=\"pre\">+FollowSymLinks</span></code>）。</p></li>\n<li><p>使用前文介绍的 <code class=\"docutils literal notranslate\"><span class=\"pre\">Alias</span></code> 指令，为合适的 URL (可能是 <a class=\"reference internal\" href=\"/zh-hans/3.1/ref/settings/#std-setting-STATIC_URL\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">STATIC_URL</span></code></a> + <code class=\"docutils literal notranslate\"><span class=\"pre\">admin/</span></code>) 取个别名，指向后台文件的实际位置。</p></li>\n<li><p>直接将后台静态文件拷贝至 Apache 的文档根目录。</p></li>\n</ol>\n</section>\n<section id=\"authenticating-against-django-s-user-database-from-apache\">\n<h2>Apache 利用 Django 的用户数据库进行验证<a class=\"heading-anchor\" href=\"#authenticating-against-django-s-user-database-from-apache\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Django 提供了一个处理器，允许 Apache 直接用 Django 的认证授权后端认证用户。参考文档 <a class=\"reference internal\" href=\"/zh-hans/3.1/howto/deployment/wsgi/apache-auth/\"><span class=\"doc\">mod_wsgi 认证授权文档</span></a>。</p>\n</section>","rootId":"how-to-use-django-with-apache-and-mod-wsgi","toc":[{"title":"基础配置","anchor":"basic-configuration","children":[]},{"title":"使用 mod_wsgi 后台模式","anchor":"using-mod-wsgi-daemon-mode","children":[]},{"title":"提供文件服务","anchor":"serving-files","children":[]},{"title":"服务后台文件","anchor":"serving-the-admin-files","children":[]},{"title":"Apache 利用 Django 的用户数据库进行验证","anchor":"authenticating-against-django-s-user-database-from-apache","children":[]}],"breadcrumbs":[{"docname":"howto/index","title":"操作指南","url":"/zh-hans/3.1/howto/"},{"docname":"howto/deployment/index","title":"部署 Django","url":"/zh-hans/3.1/howto/deployment/"},{"docname":"howto/deployment/wsgi/index","title":"如何使用 WSGI 进行部署","url":"/zh-hans/3.1/howto/deployment/wsgi/"}],"prev":{"docname":"howto/deployment/wsgi/uwsgi","title":"如何用 uWSGI 托管 Django","url":"/zh-hans/3.1/howto/deployment/wsgi/uwsgi/"},"next":{"docname":"howto/deployment/wsgi/apache-auth","title":"Apache 利用 Django 的用户数据库进行验证","url":"/zh-hans/3.1/howto/deployment/wsgi/apache-auth/"},"formats":{"html":"/zh-hans/3.1/howto/deployment/wsgi/modwsgi/","markdown":"/zh-hans/3.1/howto/deployment/wsgi/modwsgi.md","json":"/zh-hans/3.1/howto/deployment/wsgi/modwsgi.json"},"source":"https://github.com/django/django/blob/stable/3.1.x/docs/howto/deployment/wsgi/modwsgi.txt","official":"https://docs.djangoproject.com/zh-hans/3.1/howto/deployment/wsgi/modwsgi/","inVersions":["6.1","6.0","5.2","5.1","5.0","4.2","4.1","4.0","3.2","3.1","3.0","2.2","2.1","2.0"],"inLocales":["en","zh-hans","fr","ja","id","pt-br","ko","es","el","pl"]}