【问题标题】:nginx serving Django in a subdirectory through uWSGInginx 通过 uWSGI 在子目录中服务 Django
【发布时间】:2023-03-03 00:40:01
【问题描述】:

我已经浏览了一些以前的线程: How do I set subdirectory in nginx with Django how to deploy django under a suburl behind nginx Serving flask app on subdirectory nginx + uwsgi

基本的教训是,您应该只需要配置您的站点(可用)来实现这一点。我现在尝试了

的各种排列
server {
    listen 80;
    server_name www.example.com;

    location = /favicon.ico { 
        access_log off; 
        log_not_found off; 
    }

    location /static/ {
        root /path/to/project;
    }

    location /project/ {
        root            /path/to/project;
        include         /etc/nginx/uwsgi_params;
        uwsgi_param     SCRIPT_NAME /project;
        uwsgi_modifier1 30;
        uwsgi_param PATH_INFO "$1";
        uwsgi_pass      unix:/tmp/project.sock;
    }
}

当我将位置定义为“/”时,一切都运行良好(删除 SCRIPT_NAME、修饰符1、PATH_INFO 和 root 无关紧要。但尝试使用子目录总是会导致找不到页面 (404):

Request URL:    http://www.example.com/project/project

(编辑)它在请求中添加一个目录。我不明白什么?

(尝试过的forced_script_name - 不应该使用它并给其他类型的头痛 - 和uwsgi配置设置)

编辑:

location /project/ {
    root            /path/to/project;
    include         /etc/nginx/uwsgi_params;
    uwsgi_param     SCRIPT_NAME /project;
    uwsgi_pass      unix:/tmp/project.sock;
}

不工作......当我为 / 配置时,套接字在那里并且工作 - 我只是看不到我缺少什么。

更新:

location ~ /project(?<path_info>/.*|$) {
    include         /etc/nginx/uwsgi_params;
    uwsgi_pass      unix:/tmp/project.sock;
    uwsgi_param     PATH_INFO $path_info;
    uwsgi_param     SCRIPT_NAME /project;
}

这会加载网站,但所有链接都指向 http://example.com/link/to/something 而不是 http://example.com/project/link/to/something

【问题讨论】:

  • django 1.9.2, uwsgi 2.07-debian(在 ubuntu 15.10 服务器上运行)

标签: django nginx uwsgi subdirectory


【解决方案1】:

最新 Nginx/uWSGI 版本的最简洁方法

由于uwsgi_modifier1 30 在最新版本中被删除,我觉得挂载点的东西太老套了,我不得不使用newer method 在子目录中为 Django 服务:

uWSGI 配置:

[uwsgi]
socket =        /tmp/project.sock

# Requires PCRE support compiled into uWSGI
route-run =     fixpathinfo:

Nginx 配置:

location /project {
    include         /etc/nginx/uwsgi_params;
    uwsgi_pass      unix:/tmp/project.sock;
    uwsgi_param     SCRIPT_NAME /project; # Pass the URL prefix to uWSGI so the "fixpathinfo:" route-rule can strip it out
}

注意:fixpathinfo: 需要 PCRE 支持才能编译到 uWSGI。

因此,如果事情不正常,请尝试安装 libpcre 和 libpcre-dev,然后使用 pip install -I --no-cache-dir uwsgi 重新编译 uwsgi。 uWSGI 的内部路由子系统需要在编译/安装uWSGI之前安装PCRE 库。 More information on uWSGI and PCRE.

【讨论】:

    【解决方案2】:

    nginx uwsgi_modifier1 在 uWSGI 中已弃用。

    您的目标是能够从任何地方托管 wsgi 应用程序,而无需调整该应用程序以说明其服务来源。

    目前在 uWSGI 中执行此操作的方法是为每个 URI 应用组合映射挂载点,如下所示:

    [uwsgi]
    socket = 127.0.0.1:3031
    ; mount apps
    mount = /app1=app1.py
    mount = /app2=app2.py
    ; rewrite SCRIPT_NAME and PATH_INFO accordingly
    manage-script-name = true
    

    Hosting multiple apps in the same process (aka managing SCRIPT_NAME and PATH_INFO)

    mount可以代替module

    对于 Django,

    ; Before
    module = django_app.wsgi:application
    ; After
    mount = /django_app=django_app.wsgi:application
    manage-script-name = true
    

    【讨论】:

    • 终于!经过大量搜索,我发现您的解决方案很合适。谢谢!
    • 很高兴能提供帮助。让 uWSGI 正常运行是我做过的最困难的事情之一 ;-)
    【解决方案3】:

    最终放弃尝试“整齐”地做到这一点。

    最终的解决方案是创建一个我在 static_url 和项目 urls.py 文件中添加前缀的设置变量。 nginx 端没有 SCRIPT_NAME 或任何复杂的东西。

    【讨论】:

      【解决方案4】:

      如果应用程序非常简单,可以在urls.py 的一行中添加一个简单的“/prefix”,那么我更喜欢这个简单的解决方案。

      否则 "/prefix" 必须附加到 Django Sites 表中您的网站记录中的domain 列行政。在第二种解决方案中,域应该是“example.com/project”,因为 Django 必须知道域和前缀,尤其是对于正确的重定向。当然,前缀也必须从网络服务器请求的 URL 中删除,就像您现在在 nginx 设置中所做的那样。

      我通常将此类部署的验证分为两个问题:

      • 是否向 Django 报告 Web 服务器 (nginx) 预期的更短或更长的 URL?
      • 是否知道 Django 其完整的基本 URL,并且它是否始终在所有网页中使用它?

      我同时使用 nginx 日志和 Django 日志记录来查看它们中的哪一个最终被错误识别。 (你没有写足够的重要信息。)

      应该测试的一个重要案例是:验证需要身份验证的网页是否正确地来回重定向到登录页面,即使您在注销后尝试这些 URL。

      更多详情请见similar question

      【讨论】:

      • 现在的问题是如何指向不同的静态目录(在op中提到的更新之后)
      • 您的问题是网页包含对静态文件的无效引用还是nginx找不到正确的静态url?如果项目位于“/”中,我希望您可以正确提供静态文件。如果项目的动态页面位于“/project”中,则静态文件不会更改任何内容。我了解您要求使用“/project”前缀是因为您需要在同一域上进行更多项目。没有明确表示您接受经典的“/static/appname/”,例如“/static/admin”在 url 的任何地方都没有“/project”。我认为是因为您还没有指定任何内容。
      • 我已经让它工作了,所以我发现静态文件很好并且 /project/ 响应正确 - 但由于某种原因 project/app 没有给我任何东西,nginx 是将控件传递给一些默认的 project/app/index.html 处理程序 - 不是我的 django 应用程序:/
      • 嗯,问题是在更改配置的同时不断变化,有些东西停止工作,但回答的原则是一样的:如果你查看日志并查看问题是否是(目前)在 nginx 或真正在 Django 中。我尝试了一个假定的正确 url,我还查看了这个 url 是否由 Django 生成。此外 /var/log/nginx/error.log 对于 nginx 配置问题非常有用,尤其是启动时的消息。
      • 最终我放弃了,只是在我应用于项目 url 文件和 static_url 的设置中添加了一个前缀
      【解决方案5】:

      首先,删除uwsgi_modifier1 30;。 Django 将自己处理SCRIPT_NAME,不需要uWSGI 重写PATH_INFO。如果 SCRIPT_NAME 没有被 uWSGI 从标头中删除,这可能是有害的。

      其次,从 nginx 配置中删除 uwsgi_param PATH_INFO "$1";PATH_INFO 已经在 uwsgi_params 文件中定义,它应该是 $document_uri(因为它在 uwsgi_params 中),而不是 $1 如果你将 SCRIPT_NAME 传递给 django。

      在调整之后,django 应该将SCRIPT_NAME 视为 URL 前缀,并将调整 url 调度程序和 url 反转。

      【讨论】:

      • 最终结果为: location /project/ { root /path/to/project;包括/etc/nginx/uwsgi_params; uwsgi_param SCRIPT_NAME /project; uwsgi_pass unix:/tmp/project.sock; } (重启 nginx 和 uwsgi 后) - 相同的结果 = 请求 URL example.com/project/project 当我尝试浏览时example.com/project
      • 为什么要添加一个目录到那里的请求?
      猜你喜欢
      • 2012-07-02
      • 2014-02-05
      • 1970-01-01
      • 2011-03-12
      • 2012-08-10
      • 2012-05-14
      • 1970-01-01
      • 1970-01-01
      • 2012-01-20
      相关资源
      最近更新 更多