在 Apache 中运行多个 Django 项目,sys.path 被覆盖

在 Apache 中运行多个 Django 项目,sys.path 被覆盖

我一直在尝试研究如何使用 Apache VirtualHosts 进行多个 Python / Django 部署。

我遇到的问题看起来很简单,

ImportError: Could not import settings 'hub.settings' (Is it on sys.path?): No module named hub.settings, referer: proposals.internal.local

我遇到的麻烦是,proposals.internal.local 正在使用 proposals.settings,而 hub.settings 实际上来自 hub.internal.local。

如果我只运行proposal或hub,我不会遇到上述问题,但是,当我同时运行它们时 - 因为人们使用它们。 sys.path似乎针对这两个项目进行了更新。

[APACHE 配置 - HUB]

<VirtualHost *:80>

    ServerName hub.internal.local

    DocumentRoot /var/www/hub.internal.local/hub/hub/static
    Alias /static/  /var/www/hub.internal.local/hub/hub/static/

    <Directory /var/www/hub.internal.local/hub/hub/static>

        Allow from all

    </Directory>

    WSGIScriptAlias / /var/www/hub.internal.local/hub/hub/wsgi.py

</VirtualHost>

[APACHE 配置 - 建议]

<VirtualHost *:80>

    ServerName proposals.internal.local

    DocumentRoot /var/www/proposals.internal.local/proposal/proposal/static
    Alias /static/  /var/www/proposals.internal.local/proposal/proposal/static/

    <Directory /var/www/proposals.internal.local/proposal/proposal/static>

        Allow from all

    </Directory>

    WSGIScriptAlias / /var/www/proposals.internal.local/proposal/proposal/wsgi.py

</VirtualHost>

[wsgi.py - 中心]

import os
import sys

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "hub.settings")
sys.path.append('/var/www/hub.internal.local')
sys.path.append('/var/www/hub.internal.local/hub')

from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()

[wsgi.py-提案]

import os
import sys

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "proposal.settings")
sys.path.append('/var/www/proposals.internal.local')
sys.path.append('/var/www/proposals.internal.local/proposal')

from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()

显然我遗漏了一些东西,但是从文档中我没有看到任何不寻常的东西。

答案1

不要使用os.environ.setdefault()。当 Django 切换到这种设置环境变量的方式时,它搞砸了在一个 mod_wsgi 进程中托管多个应用程序。

这在我的博客中有记录:请求在 Apache/mod_wsgi 下的错误 Django 实例中运行。

如果这是原因,则有两种解决方案。最快的方法是用更常见的赋值方法代替使用 setdefault() 在 WSGI 脚本文件中设置环境变量。

os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings'

另一种方法需要做更多工作,但也有其他好处,即切换到使用 mod_wsgi 的守护进程模式来运行 Django 实例,并将每个实例委托给一组单独的进程。通过在单独的进程中运行 Django 实例,环境变量不可能从一个实例泄漏到另一个实例。

WSGIDaemonProcess project-2
WSGIScriptAlias /suburl /some/path/project-2/wsgi.py process-group=project-2

WSGIDaemonProcess project-1
WSGIScriptAlias / /some/path/project-1/wsgi.py process-group=project-1

相关内容