1

我使用 nginx 作为 apache/mod_wsgi 和 Django 的反向代理。目前,使用 / 别名我的 wsgi 文件和 /media 别名我的媒体目录一切正常。但是,我想设置它,以便 /media/foo/bar为我的 wsgi 文件加上别名,这样 /media/foo/example.txt 将使用 apache 提供 example.txt,但 /media/foo/bar/example.txt将传递给我在 Django 中的 urls.py。

我尝试将另一个 WSGIScriptAlias 添加到我的 /media/ 别名上方的 apache.conf 中,但 /media/foo/bar/example.txt 仍然由 apache 提供服务。我的 apache.conf 目前看起来像这样:

<VirtualHost *:8080>
    #DocumentRoot /var/www/mydomain.com/public
    ServerName mydomain.com
    ErrorLog /var/www/mydomain.com/logs/apache_error_log
    CustomLog /var/www/mydomain.com/logs/apache_access_log common

    WSGIScriptAlias /media/foo/bar /var/www/mydomain.com/src/myproject/server/django.wsgi
    Alias /media/ /var/www/mydomain.com/public/media/
    <Directory /var/www/mydomain.com/public/media>
        Order deny,allow
        Allow from all
    </Directory>

    WSGIScriptAlias / /var/www/mydomain.com/src/myproject/server/django.wsgi

    <Directory /var/www/mydomain.com/src/myproject/server>
        Order allow,deny
        Allow from all
    </Directory>
</VirtualHost>
4

2 回答 2

4

因为 Alias 和 WSGIScriptAlias 处于不同的优先级,所以您不能创建多于 2 级的多级重叠 URL 集,这些 URL 在使用它们之间交替使用。解决方案是对所有子 URL 使用 Alias/AliasMatch 指令,这样它们就会以相同的优先级进行评估。仍然可以使用 WSGIScriptAlias 作为站点的根目录。

因此,请尝试使用以下 with 指令,以使大多数嵌套的 URL 模式早于外部 URL。

<VirtualHost *:8080>
#DocumentRoot /var/www/mydomain.com/public
ServerName mydomain.com
ErrorLog /var/www/mydomain.com/logs/apache_error_log
CustomLog /var/www/mydomain.com/logs/apache_access_log common

AliasMatch ^/(media/foo/bar/.*) /var/www/mydomain.com/src/myproject/server/django.wsgi/$1
Alias /media/ /var/www/mydomain.com/public/media/
WSGIScriptAlias / /var/www/mydomain.com/src/myproject/server/django.wsgi

<Directory /var/www/mydomain.com/src/myproject/server>
    Options ExecCGI
    AddHandler wsgi-script .wsgi
    # WSGIApplicationGroup %{GLOBAL}
    Order allow,deny
    Allow from all
</Directory>

<Directory /var/www/mydomain.com/public/media>
    Order deny,allow
    Allow from all
</Directory>
</VirtualHost>

AliasMatch 用于最嵌套的情况,因为我们需要调整 Django 应用程序看到的 SCRIPT_NAME 的值,即挂载点,这样请求似乎仍然是针对挂载在根目录下的 Django 实例。如果不这样做,则 urls.py 模式将无法按您对该子 URL 的预期工作。使用 AliasMatch 并在使用 $1 的脚本路径后将匹配的子模式添加到 RHS 实现了这一点。

尽管 Django 通过两个不同的指令挂载,但计算出来的 SCRIPT_NAME 应该是相同的,因此应该使用相同的 Python 子解释器。如果由于某种原因您认为您的内存使用量是您期望的两倍,即,Django 的两个实例在不同的子解释器中运行,您可以通过取消注释上面的 WSGIApplicationGroup 指令来强制它们运行。虽然这不应该是必需的,如果您认为您确实需要它,最好转到 mod_wsgi 邮件列表,并可以指导您如何验证是否应该这样做以及有什么问题。

于 2009-11-11T01:50:15.837 回答
1

快速的技巧是在你的 Apache 配置中将 mod_wsgi 移动到 mod_alias 之前,但这实际上会导致 /media 被你的 Django 应用程序处理。

如果 AliasMatch 支持前瞻正则表达式,您应该可以这样做:

AliasMatch /media/(?!foo) …</p>

这应该可以避免这个问题——也就是说,我很想推荐从另一个主机名media.example.org

于 2009-11-10T18:55:27.020 回答