【问题标题】:Deploying django under a sub-URL with Nginx/Fastcgi使用 Nginx/Fastcgi 在子 URL 下部署 django
【发布时间】:2011-03-24 23:13:16
【问题描述】:

我一辈子都不知道如何使用 Nginx/fastcgi 在非 root 位置下部署 django 站点,例如http://localhost:8080/myproject/ 而不是 http://localhost:8080/;我看到的所有示例都假设 Apache 或安装在站点的根目录。这是我nginx.conf的相关部分:

server {
    listen 8080;
    server_name localhost;

    location /myproject/ {
        # host and port to fastcgi server
        fastcgi_pass 127.0.0.1:3030;

        fastcgi_param  QUERY_STRING       $query_string;
        fastcgi_param  REQUEST_METHOD     $request_method;
        fastcgi_param  CONTENT_TYPE       $content_type;
        fastcgi_param  CONTENT_LENGTH     $content_length;

        #fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
        fastcgi_param  PATH_INFO          $fastcgi_script_name;
        fastcgi_param  REQUEST_URI        $request_uri;
        fastcgi_param  DOCUMENT_URI       $document_uri;
        fastcgi_param  DOCUMENT_ROOT      $document_root;
        fastcgi_param  SERVER_PROTOCOL    $server_protocol;

        fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
        fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;

        fastcgi_param  REMOTE_ADDR        $remote_addr;
        fastcgi_param  REMOTE_PORT        $remote_port;
        fastcgi_param  SERVER_ADDR        $server_addr;
        fastcgi_param  SERVER_PORT        $server_port;
        fastcgi_param  SERVER_NAME        $server_name;
    }
}

还有一个最小的urls.py

from django.http import HttpResponse
from django.conf.urls.defaults import patterns

urlpatterns = patterns('',
    (r'^hello$', lambda request: HttpResponse('Hello world!')),

)

尝试访问 http://localhost:8080/myproject/hello 时会出现 404。我尝试了以下所有组合均未成功:

  • 评论/取消评论fastcgi_param PATH_INFO $fastcgi_script_name;
  • 评论/取消评论fastcgi_param SCRIPT_NAME $fastcgi_script_name;
  • 在 settings.py 中设置FORCE_SCRIPT_NAME = '/myproject/'

【问题讨论】:

    标签: django nginx fastcgi


    【解决方案1】:

    我自己刚刚解决了同样的问题 - 事实证明,您在 ServerFault 上提供的指向 Django change doc 的链接是解决问题的关键。

    Django > 1.0 使用 SCRIPT_NAMEPATH_INFO 来路由 URL,正如文档解释的那样。所以我拿着它跑了。对于您希望植根于 mydomain.com/myproject/ 的名为“myproject”的项目,试试这个。

    location ~ /myproject/(.*)$ {
        fastcgi_pass 127.0.0.1:8080;
        fastcgi_param  PATH_INFO /$1;
        SCRIPT_NAME /myproject;
    }
    

    我在另一个站点范围的配置文件中拥有的其余 fastcgi 参数。所以你的例子看起来像

    server {
        listen 8080;
        server_name localhost;
    
        location /myproject/ {
            # host and port to fastcgi server
            fastcgi_pass 127.0.0.1:3030;
    
            fastcgi_param  QUERY_STRING       $query_string;
            fastcgi_param  REQUEST_METHOD     $request_method;
            fastcgi_param  CONTENT_TYPE       $content_type;
            fastcgi_param  CONTENT_LENGTH     $content_length;
    
            fastcgi_param  SCRIPT_NAME        /myproject;
            fastcgi_param  PATH_INFO          /$1;
            fastcgi_param  REQUEST_URI        $request_uri;
            fastcgi_param  DOCUMENT_URI       $document_uri;
            fastcgi_param  DOCUMENT_ROOT      $document_root;
            fastcgi_param  SERVER_PROTOCOL    $server_protocol;
    
            fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
            fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;
    
            fastcgi_param  REMOTE_ADDR        $remote_addr;
            fastcgi_param  REMOTE_PORT        $remote_port;
            fastcgi_param  SERVER_ADDR        $server_addr;
            fastcgi_param  SERVER_PORT        $server_port;
            fastcgi_param  SERVER_NAME        $server_name;
        }
    }
    

    使用相同的 urls.py。到目前为止,我遇到的唯一问题是保持 DRY 的小问题,例如 settings.py 需要绝对 URL,而 Django 不认为在 URL 上添加 SCRIPT_NAME(想想 settings.LOGIN_URLsettings.MEDIA_URL)。

    这可能很明显,但也要确保您有另一个指向静态和管理媒体的位置。

    【讨论】:

    • @gsakkis,这对你有帮助吗?
    • 它帮助了我...我使用这种方法在 nginx.conf 中的同一台服务器上托管了两个 webapp。{}但我的问题是两者都需要不同的静态和媒体网址......在这里做什么??
    【解决方案2】:

    试试这个配置

        location  /myproject {
        fastcgi_split_path_info ^(/myproject)(.*)$;
        fastcgi_pass 127.0.0.1:8080;
        include fastcgi_params;
    }
    

    其中,fastcgi_params 文件包含

        fastcgi_param  QUERY_STRING       $query_string;
        fastcgi_param  REQUEST_METHOD     $request_method;
        fastcgi_param  CONTENT_TYPE       $content_type;
        fastcgi_param  CONTENT_LENGTH     $content_length;
    
        fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
        fastcgi_param  REQUEST_URI        $request_uri;
        fastcgi_param  DOCUMENT_URI       $document_uri;
        fastcgi_param  DOCUMENT_ROOT      $document_root;
        fastcgi_param  SERVER_PROTOCOL    $server_protocol;
    
        fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
        fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;
    
        fastcgi_param  REMOTE_ADDR        $remote_addr;
        fastcgi_param  REMOTE_PORT        $remote_port;
        fastcgi_param  SERVER_ADDR        $server_addr;
        fastcgi_param  SERVER_PORT        $server_port;
        fastcgi_param  SERVER_NAME        $server_name;
    
        fastcgi_param  PATH_INFO          $fastcgi_path_info;
    
        # PHP only, required if PHP was built with --enable-force-cgi-redirect
        fastcgi_param  REDIRECT_STATUS    200;
    

    它对我有用。

    请参阅有关 fastcgi_split_path_info 的文档

    【讨论】:

      【解决方案3】:

      因为我自己遇到了子 URL 问题,所以偶然发现了您的问题。我的服务器使用 Apache 作为其主服务器,所以我的配置有所不同,但它可以工作。也许这会对某人有所帮助:

      • Apache 在端口 80(主 Web 服务器)上
      • localhost:3033 上的 nginx(随机端口)
      • 在 localhost:3034 上的 manage.py fastcgi

      那么 Apache 配置看起来像这样(nginx 的代理):

      <Location /blogsite/>
          Order deny,allow
          Allow from all
      
          ProxyPass http://127.0.0.1:3033/
          ProxyPassReverse http://127.0.0.1:3033/
      </Location>
      

      而nginx站点配置为:

      server {
          listen 127.0.0.1:3033;
          server_name localhost;
      
          location / {
              fastcgi_pass 127.0.0.1:3034;
              fastcgi_param PATH_INFO $fastcgi_script_name;
              fastcgi_param REQUEST_METHOD $request_method;
              fastcgi_param QUERY_STRING $query_string;
              fastcgi_param CONTENT_TYPE $content_type;
              fastcgi_param CONTENT_LENGTH $content_length;
              fastcgi_pass_header Authorization;
              fastcgi_intercept_errors off;
          }
      
          access_log  /var/log/nginx/blogsite.access_log;
          error_log   /var/log/nginx/blogsite.error_log;
      }
      

      我认为您遇到的问题是由于某种方式的 nginx 配置,而不是 Django 部署的问题。您可能想试试我发布的解决方案是否适合您。

      【讨论】:

        猜你喜欢
        • 2012-03-07
        • 2011-12-29
        • 2012-11-09
        • 1970-01-01
        • 2018-01-18
        • 2012-05-02
        • 2010-10-06
        • 2011-02-05
        • 2013-07-04
        相关资源
        最近更新 更多