在子路径运行Django应用程序通过的nginx + uwsgi(Run django app vi

2019-06-25 23:50发布

我想在我们的开发服务器上的一个子目录别名运行一个简单的测试项目。 基本设置是与传递一个子目录中的WSGI应用程序的一切的位置Nginx上。

Django的显然不明白,它在子目录中的别名,这完全破坏URL生成和解析运行。
我找不到在该文档中的任何前缀般的环境和我的谷歌赋也没有帮助,多...所以我不是问在这里。

我发现的唯一的事情就是设置FORCE_SCRIPT_NAME至少修复URL生成。 (参见: http://docs.webfaction.com/software/django/config.html#mounting-a-django-application-on-a-subpath )
可悲的是这并没有解决URL配置解析,即使提到的网站表明。

是否有可能在一个子目录别名运行Django应用程序,如果是这样,如何?

nginx的配置:

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

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

编辑

因此,制定 “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)),
)

我认为正在发生的事情:当管理员用正则表达式“^管理员”和实际的URL开始是“fancyprojectname /管理/”,Django的不正确匹配的网址,即使SCRIPT_NAME设置。

解决方案

因此,它确实与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的现在可以生成和匹配的网址正确。

Answer 1:

这是错误的:

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

Django的理解,并透明地处理它。 服务器应设置SCRIPT_NAME自己:你发现自己使用的事实FORCE_SCRIPT_NAME显示,问题出在你的Nginx的配置,而不是在Django。

我怀疑,问题是使用的location ,而不是更合适的指令。 不幸的是我对Nginx的/ uwsgi没有专家。 在阿帕奇/ mod_wsgi的,你可以这样做:

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

告诉mod_wsgi的该网站开始于mysite ,而不是根源。 目前几乎可以肯定的nginx / uwsgi类似命令。



Answer 2:

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

location / {
    uwsgi_pass unix:/tmp/fancyprojectname.socket;
    include /etc/nginx/uwsgi_params;
}

那么这将在工作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;
}

...而且也没有必要设置FORCE_SCRIPT_NAME在你的Django设置。

参考文献:

  • 斯特雷耶的原始意见和解决方案,张贴在的问题。
  • https://uwsgi-docs.readthedocs.org/en/latest/Nginx.html
  • https://www.python.org/dev/peps/pep-0333/ (全WSGI规范)


Answer 3:

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

uWSGI配置:

[uwsgi]
route-run = fixpathinfo:

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;
    }
}

如果不能解决问题:尝试安装libpcre和libpcre-dev的,然后再重新安装uwsgi与pip install -I --no-cache-dir uwsgi 。 uWSGI的内部路由子系统需要之前 uWSGI编译/安装要安装的PCRE库。 在uWSGI和PCRE的更多信息。



文章来源: Run django app via nginx+uwsgi in a subpath
标签: django nginx