开发者

Deploying django under a sub-URL with Nginx/Fastcgi

I can't for the life of me figure out how to deploy a django site under a non-root location with Nginx/fastcgi, e.g. http://localhost:8080/myproject/ instead of http://localhost:8080/; all the examples I have seen either assume Apache or mounting at the root of the site. Here's the relevant part of my 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开发者_StackOverflow中文版_param  SERVER_NAME        $server_name;
    }
}

And a minimal urls.py:

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

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

)

Trying to access http://localhost:8080/myproject/hello gives a 404. I've tried unsuccessfully all combinations of:

  • Commenting/uncommenting fastcgi_param PATH_INFO $fastcgi_script_name;
  • Commenting/uncommenting fastcgi_param SCRIPT_NAME $fastcgi_script_name;
  • Setting FORCE_SCRIPT_NAME = '/myproject/' in settings.py.


Just pushed through the same issue myself- it turns out that the link you provided on ServerFault to the Django change doc was the key to solving the problem.

Django > 1.0 uses SCRIPT_NAME and PATH_INFO to route URLs, as the doc explained. So I took that and ran with it. For a project called 'myproject', which you'd like rooted at mydomain.com/myproject/, try this.

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

The rest of the fastcgi params I have in another site-wide config file. So your example would look something like

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

with the same urls.py. The only issues I've had so far have been minor troubles keeping DRY, eg where settings.py requires absolute URLs and Django doesn't think to prepend the SCRIPT_NAME on the URL (think settings.LOGIN_URL, settings.MEDIA_URL).

This might be obvious, but also make sure you have another location that points to your static and admin media.


Try this conf

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

where, fastcgi_params file contains

    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;

It worked for me.

see documentation about fastcgi_split_path_info


Stumbled over your question as I had the sub-URL problem myself. My server uses Apache as its main server, so my configuration is different, but it works. Maybe this will help somebody:

  • Apache on port 80 (main web server)
  • nginx on localhost:3033 (random port)
  • manage.py fastcgi on localhost:3034

Then the Apache config looks like this (proxy to nginx):

<Location /blogsite/>
    Order deny,allow
    Allow from all

    ProxyPass http://127.0.0.1:3033/
    ProxyPassReverse http://127.0.0.1:3033/
</Location>

And the nginx site configuration is:

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

I think the problem you have is due to the nginx configuration somehow, not really a problem with Django deployment. You may want to try out if my posted solution works for you.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜