使用mod_wsgi在Apache上部署多个Django应用程序

25
我想在同一台主机上部署两个不同的 Django 应用程序:第一个对应于 URL /site1,第二个对应于 URL /site2。以下是我的配置:
LoadModule wsgi_module modules/mod_wsgi.so
WSGIScriptAlias /site1 /var/www/py/site1/site1/wsgi.py WSGIScriptAlias /site2 /var/www/py/site2/site2/wsgi.py
WSGIPythonPath /var/www/py/site1:/var/www/py/site2
<Directory "/var/www/py/site1/site1"> <Files wsgi.py> Order deny,allow Allow from all </Files> </Directory> <Directory "/var/www/py/site2/site2"> <Files wsgi.py> Order deny,allow Allow from all </Files> </Directory>
此外,这是两个应用程序的 wsgi.py 文件:
import os
import sys

path = '/var/www/py/site1'
if path not in sys.path:
    sys.path.append(path)
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "site1.settings") from django.core.wsgi import get_wsgi_application application = get_wsgi_application()
现在,我遇到了一个问题。当我访问我的服务器时,例如 http://app1.sites.gr/site1 有时会加载 site1,而有时会加载 site2!!!当我访问 http://app1.sites.gr/site2 时也是一样的情况...有时我会得到 site1 的欢迎页面,有时我会得到 site2 的欢迎页面!我按 F5 键并且每次都看到不同的欢迎页面。我已经检查了几个小时并没有发现任何奇怪的地方...
请告诉我可能的问题是什么,以免让我疯掉...
谢谢!
3个回答

51

这是由Django 1.4生成的wsgi.py文件存在的问题。即使在单独的子解释器中,当尝试在同一个进程中托管两个不同的Django实例时,它也无法正常工作。

修改:

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "site1.settings")

至:

os.environ["DJANGO_SETTINGS_MODULE"] = "site1.settings"

或者更好的方式是使用守护进程模式,并将每个进程分配到不同的守护进程组中运行。

也就是说,不要这样做:

WSGIScriptAlias /site1 /var/www/py/site1/site1/wsgi.py
WSGIScriptAlias /site2 /var/www/py/site2/site2/wsgi.py

WSGIPythonPath /var/www/py/site1:/var/www/py/site2

使用:

WSGIDaemonProcess site1 python-path=/var/www/py/site1
WSGIScriptAlias /site1 /var/www/py/site1/site1/wsgi.py process-group=site1 application-group=%{GLOBAL}

WSGIDaemonProcess site2 python-path=/var/www/py/site2
WSGIScriptAlias /site2 /var/www/py/site1/site2/wsgi.py process-group=site2 application-group=%{GLOBAL}

更新

注意,现在已经有一篇关于这个问题和其他原因的博客文章。


2
这真的起作用了,谢谢!但是我现在有另一个问题:当我尝试在同一个浏览器中访问两个站点时,有时会从site1(当我访问site2)注销我 - 但反之则不然...这可能是因为我有/site1和/site2吗?我应该尝试Erik提出的方法,使用site1.sites.gr和site2.sites.gr吗? - Serafeim
4
由于这些站点位于同一域名下,您需要为每个站点分别设置SESSION_COOKIE_NAME或SESSION_COOKIE_PATH。请参见http://code.google.com/p/modwsgi/wiki/IntegrationWithDjango。 - Graham Dumpleton

1
您的应用程序监听在同一个端口上,并且似乎没有代理将它们委托给不同的端口。
您可以在 Apache 中设置 VirtualHosts,或使用 Nginx、Lighttpd 或其他工具创建适当的代理。

我能否通过不同的URL(site1 vs site2)委派给正确的脚本?我不想使用不同的端口或配置代理!我只想在同一台Apache主机上运行两个Django应用程序-我已经在其他地方读到过这是可能的:( - Serafeim
那我应该在不同的端口上使用gunicorn运行我的两个站点,然后只需在我的httpd.conf文件中为两个站点添加以下内容“ProxyPass /site1 http://127.0.0.1:8111/ ProxyPassReverse /site1 http://127.0.0.1:8111/”吗? - Serafeim
我以为你只想使用Apache,在这种情况下,请使用VirtualHosts http://httpd.apache.org/docs/2.2/vhosts/examples.html - Hedde van der Heide
好的,我真正想做的是我所问的...有sites.gr/site1和sites.gr/site2 - 每个站点指向自己的Django应用程序...但据我所知不可能 :( - Serafeim
使用Apache和虚拟主机是完全可行的,我甚至可以给您发送一个示例,只需要一些额外的设置来处理静态文件和WSGI分配。 - Hedde van der Heide

1
Graham Dumpleton的回复可能是你最想要仔细阅读的,但我建议你将两个Django托管在不同子域的根目录下,而不是在同一域名的非根位置。在我看来,运行非根Django站点有很多陷阱。
祝好运!

2
经过大约8个月的(不是很频繁的)生产使用,包括四个不同的站点(/site1,/site2,site3和site4),一切都运行得非常顺利(是的,即使是SESSION_COOKIE_NAME设置的会话也是如此)!唯一需要记住的是永远不要使用绝对URL,而只能通过反向和{% url %} -- 毕竟这是Django-DRY方式 :) - Serafeim

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接