Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

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. localhost:8080/myproject/ instead of 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_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 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.
share|improve this question
add comment

4 Answers

Just pushed through the same issue myself- it turns out that the link you provided 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.

share|improve this answer
add comment

I ran into related problem with Nginx and Gunicorn instead of fastcgi.

I wrote about my findings here:

http://albertoconnor.ca/blog/2011/Sep/15/hosting-django-under-different-locations

The upshot is you can use proxy_set_header to set the SCRIPT_NAME header directly into the HTTP headers.

share|improve this answer
add comment

I believe the issue lies in your django setup rather than the nginx and fastcgi setup. You have the urls's defined as http://hostname.domain.tld/hello and not http://hostname.domain.tld/myproject/hello

So as far as django is concerned the request does not match any url is has mapped.

Please try the following in your urls.py : urlpatterns = patterns('', (r'^myproject/hello$', lambda request: HttpResponse('Hello world!')),

HTH

MartinP

share|improve this answer
1  
Yeah this works but urlconfs are supposed to be easily relocatable, i.e. moving your app under a different root should not require changing all your urls. Instead I should somehow tell Nginx to pass /myproject/ as SCRIPT_NAME to Django: code.djangoproject.com/wiki/… –  gsakkis Sep 7 '10 at 10:08
add comment

For Django 1.6< according to other threads on ServerFault, you should not set the SCRIPT_NAME variable, this one should be '', and you should set only PATH_INFO with $fastcgi_script_name variable.

For Django 1.6> according to the changes... this settings are no longer necessary, https://code.djangoproject.com/wiki/BackwardsIncompatibleChanges#ChangedthewayURLpathsaredetermined.I have commented out both the Path info and Script Name lines in fastcgi_params (in Debian-like cases) or in the nginx.conf (RHEL cases)

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.