使用Apache和mod_wsgi实现多个Django站点

63

我想在同一台使用Debian 5的服务器上托管几个网站,假设我的IP地址是155.55.55.1,其中包括site1site2site3

site1: 155.55.55.1:80  , script at /opt/django/site1/
site2: 155.55.55.1:8080, script at /opt/django/site2/
site3: 155.55.55.1:8090, script at /opt/django/site3/

这是我的 Apache 默认配置:

<VirtualHost *:80>
    ServerName /
    ServerAlias  */
    DocumentRoot /opt/django/site1/
    LogLevel warn
    WSGIScriptAlias / /opt/django/site1/apache/django.wsgi
    Alias /media /opt/django/site1/media/statics
    Alias /admin_media  /home/myuser/Django-1.1/django/contrib/admin/media 
</VirtualHost>

<VirtualHost *:80>
    DocumentRoot "/usr/share/phpmyadmin"
    ServerName /phpmyadmin
    Alias /phpmyadmin /usr/share/phpmyadmin
    <Directory /usr/share/phpmyadmin>
        Options Indexes FollowSymLinks
        AllowOverride None
        Order Deny,Allow
        Allow from all
    </Directory>
</VirtualHost>

这是我用于 site1 的 WSGI 配置,位于 /opt/django/site1/apache/django.wsgi

import os, sys
import django.core.handlers.wsgi

sys.path.append('/opt/django')
sys.path.append('/opt/django/site1')

os.environ['DJANGO_SETTINGS_MODULE'] = 'site1.settings'
application = django.core.handlers.wsgi.WSGIHandler()

如何添加基于Django的网站site2site3,并像site1一样提供服务?


我已经编辑了我的问题,很抱歉忘记了 :) - Hellnar
2个回答

110

您的ServerName/ServerAlias指令是错误的。 ServerName应该是主机名。 您可能只需删除ServerAlias。

然后,显然地复制VirtualHost/Listen指令,只需更改端口号和文件系统中脚本的位置。

最后,不要将DocumentRoot设置为Django代码所在的位置,因为如果Apache配置出错,这将更容易意外地将源代码暴露给下载。因此,只需从Django站点的VirtualHost中删除DocumentRoot指令即可。

Listen 80

<VirtualHost *:80>
ServerName www.example.com
WSGIScriptAlias / /opt/django/site1/apache/django.wsgi
Alias /media /opt/django/site1/media/statics
Alias /admin_media  /home/myuser/Django-1.1/django/contrib/admin/media

<Directory opt/django/site1/apache>
Order allow,deny
Allow from all
</Directory>

<Directory /home/myuser/Django-1.1/django/contrib/admin/media>
Order allow,deny
Allow from all
</Directory>
</VirtualHost>

Listen 8080

<VirtualHost *:8080>
ServerName www.example.com
WSGIScriptAlias / /opt/django/site2/apache/django.wsgi
Alias /media /opt/django/site2/media/statics
Alias /admin_media  /home/myuser/Django-1.1/django/contrib/admin/media

<Directory opt/django/site2/apache>
Order allow,deny
Allow from all
</Directory>

<Directory /home/myuser/Django-1.1/django/contrib/admin/media>
Order allow,deny
Allow from all
</Directory>
</VirtualHost>

Listen 8090

<VirtualHost *:8090>
ServerName www.example.com
WSGIScriptAlias / /opt/django/site3/apache/django.wsgi
Alias /media /opt/django/site3/media/statics
Alias /admin_media  /home/myuser/Django-1.1/django/contrib/admin/media

<Directory opt/django/site3/apache>
Order allow,deny
Allow from all
</Directory>

<Directory /home/myuser/Django-1.1/django/contrib/admin/media>
Order allow,deny
Allow from all
</Directory>
</VirtualHost>

我还添加了缺失的Directory指令以允许访问静态文件。但是您应该检查路径。

请确保阅读以下内容:

http://code.google.com/p/modwsgi/wiki/IntegrationWithDjango http://code.google.com/p/modwsgi/wiki/ConfigurationGuidelines#Hosting_Of_Static_Files

以获取更多信息。


更新 1

顺便说一下,由于您在同一个Apache中使用PHP,因此最好使用mod_wsgi守护程序模式,并将每个Django实例推送到自己单独的进程中。这样可以使这些进程成为多线程的,即使主Apache进程由于PHP而被强制成为单线程。最终结果将比在嵌入模式下在每个进程中运行多个Django实例且使用预分配MPM时使用的内存要少得多。您的Django代码只需要是线程安全的。配置除了上述之外,还需要为每个Django VirtualHost添加WSGIDaemonProcess / WSGIProcessGroup,其中守护进程组的名称对于每个VirtualHost都不同。

<VirtualHost *:80>
WSGIDaemonProcess site1 display-name=%{GROUP}
WSGIProcessGroup site1
... existing stuff
</VirtualHost>

<VirtualHost *:8080>
WSGIDaemonProcess site2 display-name=%{GROUP}
WSGIProcessGroup site2
... existing stuff
</VirtualHost>

<VirtualHost *:8090>
WSGIDaemonProcess site3 display-name=%{GROUP}
WSGIProcessGroup site3
... existing stuff
</VirtualHost>

这也使得您可以更容易地重新启动每个Django实例而不需要重启整个Apache。阅读:

http://code.google.com/p/modwsgi/wiki/QuickConfigurationGuide#Delegation_To_Daemon_Process http://code.google.com/p/modwsgi/wiki/ReloadingSourceCode


2
哇,谢谢你的温和详细的解释,Graham!我正在为我的公司内部运行我的网站,所以它没有域名,只有一个内部 DNS,并且只能通过 http://mysite/ 在本地访问,在这种情况下,我应该将 ServerName www.example.com 更改为 ServerName mysite 吗? - Hellnar
1
我也喜欢在WSGIDaemonProcess行中添加python-path,以利用virtualenv并将我的python site-packages本地化到某个智能位置。 - rjmoggach
1
如果使用mod_wsgi 3.4,最好使用新的python-home选项而不是python-path。 - Graham Dumpleton
@GrahamDumpleton您说过DocumentRoot不应该在虚拟主机中,那我应该把它放在哪里呢?或者对于Django应用程序没有必要使用Document root。PHP虚拟配置是否也适用相同的规则? - user1958218
2
我并没有说“DocumentRoot不应该在虚拟主机中”。我说的是“不要将DocumentRoot设置为Django代码所在的位置”。DocumentRoot指的是一个目录。如果WSGIScrtipAlias未定义,Apache将从DocumentRoot列出的目录中提供文件。因此,将DocumentRoot引用到源代码所在的目录是不明智的,因为如果某些原因未应用WSGIScriptAlias,则用户可以下载您的源代码。 - Graham Dumpleton
1
在CentOS 6上,我遇到了“Permission denied: mod_wsgi...Unable to connect to WSGI daemon process...”的问题。解决方法是将“WSGISocketPrefix /var/run/wsgi”添加到我的主要apache配置文件中,即在“VirtualHost”设置之外。此外,以守护进程模式运行mod_wsgi解决了一些我看到的“can't pickle...”错误。请参见thisthis - Banjer

2
将所有的虚拟主机配置放在一个地方是可行的,但Debian有自己的概念,将它们分别存储在/etc/apache2/sites-available中的每个站点文件中,并通过在../sites-enabled中创建符号链接来激活它们。这样,服务器管理员还可以为每个站点管理员Unix用户分配单独的访问权限,脚本可以检查站点是否处于活动状态等。
基本上,拥有一个集中的Django-Admin安装指南会很好,目前分散的文档、链接和博客文章并不真正有助于Django的推广。

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