我一直在尝试研究如何使用 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