使用Nginx / Fastcgi在子URL下部署django

时间:2010-08-03 21:12:28

标签: django nginx fastcgi

我不能为我的生活弄清楚如何使用Nginx / fastcgi在非根位置部署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/'

3 个答案:

答案 0 :(得分:7)

我自己也推翻了相同的问题 - 事实证明,您在ServerFault上提供给Django change doc的链接是解决问题的关键。

Django> 1.0正如文档所解释的那样,使用SCRIPT_NAMEPATH_INFO来路由URL。所以我接受了它,并与它一起运行。对于一个名为'myproject'的项目,你想要植根于mydomain.com/myproject/,试试这个。

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

我在另一个站点范围的配置文件中使用了fastcgi params的其余部分。所以你的例子看起来像

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_URL,{ {1}})。

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

答案 1 :(得分:3)

试试这个conf

    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

的文档

答案 2 :(得分:0)

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

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

然后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部署的问题。如果我发布的解决方案适合你,你可能想试试。