在子路径中通过nginx + uwsgi运行django app

Str*_*yer 15 django nginx

我想在我们的开发服务器上的子目录别名中运行一个简单的测试项目.基本设置是一个nginx,其位置将子目录中的所有内容传递给wsgi应用程序.

Django显然不明白它运行在子目录别名中,这完全破坏了URL的生成和解析.
我在文档中找不到任何类似前缀的设置,而我的谷歌也没有那么多帮助...所以我在这里问.

我找到的唯一一件事是设置FORCE_SCRIPT_NAME,它至少修复了URL的生成.(参见:http:
//docs.webfaction.com/software/django/config.html#mounting-a-django-application-on-a-subpath )遗憾的是,这并不能修复urlconf解析,即使提到的网站建议那.

是否可以在子目录别名中运行django应用程序,如果是,如何?

nginx配置:

server {
        location /fancyprojectname/static {
                alias /srv/fancyprojectname/static;
        }

        location /fancyprojectname/ {
                uwsgi_pass unix://var/run/uwsgi/app/fancyprojectname/socket;
                include uwsgi_params;
        }
}
Run Code Online (Sandbox Code Playgroud)

编辑

所以,设置"uwsgi_param SCRIPT_NAME/fancyprojectname;" 在nginx位置使FORCE_SCRIPT_NAME变得不必要 - 遗憾的是,URL匹配仍然不起作用.

from django.conf.urls import patterns, include, url

# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('',
    # Uncomment the admin/doc line below to enable admin documentation:
    # url(r'^admin/doc/', include('django.contrib.admindocs.urls')),

    # Uncomment the next line to enable the admin:
    url(r'^admin/', include(admin.site.urls)),
)
Run Code Online (Sandbox Code Playgroud)

我认为发生了什么:由于管理员正则表达式以"^ admin"开头且实际URL为"fancyprojectname/admin /",因此即使设置了SCRIPT_NAME,Django也无法正确匹配URL.

解决方案

所以,SCRIPT_NAME确实存在问题.

WSGI规范说以下内容:

SCRIPT_NAME请求URL的"路径"的初始部分,对应于应用程序对象,以便应用程序知道其虚拟"位置".如果应用程序对应于服务器的"根",则这可以是空字符串.

PATH_INFO请求URL的"路径"的其余部分,指定应用程序中请求目标的虚拟"位置".如果请求URL以应用程序根目标为止,并且没有尾部斜杠,则此字符串可能为空字符串.

Nginx不会自动设置SCRIPT_NAME,因此无论如何都需要设置.之后PATH_INFO是错误的,因为在默认设置中,Nginx将其设置为$ document_uri,这将是完整的URL.

"uwsgi_modifier1 30;" 告诉Nginx设置UWSGI_MODIFIER_MANAGE_PATH_INFO,然后告诉UWSGI剥离PATH_INFO的SCRIPT_NAME.

这些设置的组合似乎有效,因为Django现在可以正确生成AND匹配URL.

Dan*_*man 8

这是假的:

Django显然不明白它运行在子目录别名中,这完全破坏了URL的生成和解析.

Django 确实理解这一点,并透明地处理它.服务器应该设置SCRIPT_NAME自己:你发现自己使用的事实FORCE_SCRIPT_NAME表明问题在于你的Nginx配置,而不是在Django中.

我怀疑问题是使用location,而不是更合适的指令.不幸的是,我不是Nginx/uwsgi的专家.在Apache/mod_wsgi中,您可以这样做:

WSGIScriptAlias /mysite /usr/local/django/mysite/apache/django.wsgi
Run Code Online (Sandbox Code Playgroud)

告诉mod_wsgi该站点是从哪个开始mysite,而不是根.几乎可以肯定,nginx/uwsgi也有类似的命令.

  • 看起来它现在正在运行 - SCRIPT_NAME并非如此,设置"uwsgi_modifier1 30;" 虽然这样做.我不知道这个设置是做什么的,但当我发现我会再次更新问题并接受这个作为有效的答案.谢谢你的指针! (5认同)
  • 好的,我试过"uwsgi_param SCRIPT_NAME/fancyprojectname;" 在nginx中,这似乎"有效",因为我现在可以在设置中注释掉FORCE_SCRIPT_NAME并正确生成URL - 但这仍然无法修复URL匹配.我会在问题中附加当前的url配置. (3认同)

dav*_*one 5

如果在http://www.example.com/(您的基域)托管Django站点时此Nginx位置块工作:

location / {
    uwsgi_pass unix:/tmp/fancyprojectname.socket;
    include /etc/nginx/uwsgi_params;
}
Run Code Online (Sandbox Code Playgroud)

然后这将在http://www.example.com/subpath/(基域上的子路径)上工作:

location /subpath {
    uwsgi_pass unix:/tmp/fancyprojectname.socket;
    uwsgi_param SCRIPT_NAME /subpath; # explicitly set SCRIPT_NAME to match subpath
    uwsgi_modifier1 30; # strips SCRIPT_NAME from PATH_INFO (the url passed to Django)
    include /etc/nginx/uwsgi_params;
}
Run Code Online (Sandbox Code Playgroud)

...并且无需在Django设置中设置FORCE_SCRIPT_NAME.

参考文献:


Sha*_*ane 5

现在,uwsgi_modifier1 30删除的Nginx的和uWSGI(我不喜欢使用一些哈克重写规则)的最新版本,我必须找到一个新的方法来得到它的工作:

uWSGI 配置:

[uwsgi]
# Requires PCRE support compiled into uWSGI
route-run = fixpathinfo:
Run Code Online (Sandbox Code Playgroud)

Nginx 配置

server {
    location /fancyprojectname/static {
        alias /srv/fancyprojectname/static;
    }

    location /fancyprojectname {
        uwsgi_pass unix://var/run/uwsgi/app/fancyprojectname/socket;
        uwsgi_param SCRIPT_NAME /fancyprojectname; # Pass the URL prefix to uWSGI so the "fixpathinfo:" route-rule can strip it out
        include uwsgi_params;
    }
}
Run Code Online (Sandbox Code Playgroud)

如果这不能解决它:尝试安装 libpcre 和 libpcre-dev,然后使用pip install -I --no-cache-dir uwsgi. uWSGI 的内部路由子系统需要在编译/安装 uWSGI之前安装 PCRE 库。有关 uWSGI 和 PCRE 的更多信息。