Deploying django under a sub-URL with Nginx/Fastcgi
Solution 1
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.
Solution 2
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.
Related videos on Youtube
Radovan Omorjan
Updated on September 18, 2022Comments
-
Radovan Omorjan over 1 year
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.
- Commenting/uncommenting
-
Radovan Omorjan over 13 yearsYeah 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/
asSCRIPT_NAME
to Django: code.djangoproject.com/wiki/…