在子路径中通过nginx + uwsgi运行django应用程序 [英] Run django app via nginx+uwsgi in a subpath

查看:139
本文介绍了在子路径中通过nginx + uwsgi运行django应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在我们的开发服务器的子目录别名中运行一个简单的测试项目。基本设置是一个带有位置的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 config:

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

location / fancyprojectname / {
uwsgi_pass unix:// var / run / uwsgi / app / fancyprojectname / socket;
包括uwsgi_params;
}
}

修改



所以,设置uwsgi_param SCRIPT_NAME / fancyprojectname;在nginx位置使FORCE_SCRIPT_NAME不必要 - 可悲的是,URL匹配仍然不起作用。

 从django.conf.urls导入模式, include,url 

#取消注释下面两行以启用admin:
from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('',
#取消注释下面的admin / doc行以启用管理员文档:
#url(r'^ admin / doc /',include('django.contrib.admindocs.urls' )),

#取消注释下一行以启用admin:
url(r'^ admin /',include(admin.site.urls)),

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



解决方案 >

所以,这确实是SCRIPT_NAME的问题。



Th e 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_MODIFIER_MANAGE_PATH_INFO则反过来告诉UWSGI取消PATH_INFO的SCRIPT_NAME。



这些设置的组合似乎起作用,因为Django现在可以生成AND

解决方案

这是错误的:


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


Django 明白,并透明地处理它。服务器应该设置SCRIPT_NAME本身:您发现自己使用FORCE_SCRIPT_NAME的事实表明问题出在您的Nginx配置中,而不是在Django中。



我怀疑问题是使用位置,而不是更合适的指令。不幸的是,我不是Nginx / uwsgi的专家。在Apache / mod_wsgi中,您可以执行以下操作:

  WSGIScriptAlias / mysite / usr / local / django / mysite / apache / django。 wsgi 

告诉mod_wsgi该网站从 mysite开始而不是根。 nginx / uwsgi几乎肯定有类似的命令。


I want to run a simple test project in a subdirectory alias on our development server. The basic setup is an nginx with a location that passes everything in a subdirectory to the wsgi application.

Django obviously does not understand that it runs in an subdirectory alias, which completely destroys URL generation and parsing.
I could not find any prefix-like setting in the docs and my google fu also did not help that much... so I'm asking here instead.

The only thing I did find was the setting FORCE_SCRIPT_NAME which at least fixes the URL generation. (see: http://docs.webfaction.com/software/django/config.html#mounting-a-django-application-on-a-subpath)
Sadly this does not fix the urlconf parsing, even though the mentioned site suggests that.

Is it possible to run a django application in a subdirectory alias and if so, how?

nginx config:

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

        location /fancyprojectname/ {
                uwsgi_pass unix://var/run/uwsgi/app/fancyprojectname/socket;
                include uwsgi_params;
        }
}

Edit

So, setting "uwsgi_param SCRIPT_NAME /fancyprojectname;" in the nginx location makes FORCE_SCRIPT_NAME unnecessary - sadly the URL matching still does not work.

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)),
)

What I think what is happening: As the admin regex starts with "^admin" and the actual URL is "fancyprojectname/admin/", Django can't match the URLs correctly, even though the SCRIPT_NAME is set.

The solution

So, it was indeed a problem with SCRIPT_NAME.

The WSGI specification says the following:

SCRIPT_NAME The initial portion of the request URL's "path" that corresponds to the application object, so that the application knows its virtual "location". This may be an empty string, if the application corresponds to the "root" of the server.

PATH_INFO The remainder of the request URL's "path", designating the virtual "location" of the request's target within the application. This may be an empty string, if the request URL targets the application root and does not have a trailing slash.

Nginx does not set SCRIPT_NAME automatically, so this needs to be set in any case. Afterwards PATH_INFO is wrong, because in the default setup Nginx sets this to $document_uri, which would be the full URL.

"uwsgi_modifier1 30;" tells Nginx to set UWSGI_MODIFIER_MANAGE_PATH_INFO, which in turn tells UWSGI to strip off the SCRIPT_NAME of the PATH_INFO.

The combination of these settings seem to work, as Django can now generate AND match URLs correctly.

解决方案

This is false:

Django obviously does not understand that it runs in an subdirectory alias, which completely destroys URL generation and parsing.

Django does understand that, and deals with it transparently. The server should be setting SCRIPT_NAME itself: the fact that you find yourself using FORCE_SCRIPT_NAME shows that the problem lies in your Nginx configuration, rather than in Django.

I suspect that the issue is the use of location, rather than a more suitable directive. Unfortunately I'm no expert on Nginx/uwsgi. In Apache/mod_wsgi, you would do this:

WSGIScriptAlias /mysite /usr/local/django/mysite/apache/django.wsgi

to tell mod_wsgi that site starts at mysite, rather than the root. There is almost certainly a similar command with nginx/uwsgi.

这篇关于在子路径中通过nginx + uwsgi运行django应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆