Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to host a Django project in a subpath?

I am building an API with Django REST framework which is served via Gunicorn and Nginx. The project "exampleproject" has to run at a subpath such as: https://100.100.100.100/exampleproject (example IP address). I do not have a domain name registered for the IP.

Currently, the start page renders as expected at https://100.100.100.100/exampleproject. However a the resource path for "products" does not work. Instead of https://100.100.100.100/exampleproject/products the start page displays https://100.100.100.100/products - which does not work.

I configured the subpath for exampleproject in /etc/nginx/sites-enabled/default as follows:

server {

    # ...

    location /exampleproject/ {
        proxy_pass        http://localhost:8007/;
        proxy_set_header  X-Real-IP  $remote_addr;
        proxy_set_header  Host $host;
        proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header  X-Forwarded-Proto $scheme;
    }

When I manually visit https://100.100.100.100/exampleproject/products Nginx records the following in /var/log/nginx/access.log:

"GET /products/ HTTP/1.1" 404 151 "-"

like image 201
JJD Avatar asked Jan 26 '15 10:01

JJD


Video Answer


2 Answers

Just remove the trailing slash from the proxy pass URL, like this:

proxy_pass http://localhost:8007;

If proxy_pass is specified without a URI, the request URI is passed to the server in the same form as sent by a client when the original request is processed, then keeping the /exampleproject/ part.

See: http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass

Then you will need to configure Django to understand the URLs under /exampleproject/.

First, you can prepend the subpath to all URLs by updating the urls.py file like this:

urlpatterns = [url(r'^exampleproject/', include(urlpatterns))]

And, in case you are serving statics and media just update in the settings:

MEDIA_URL = '/exampleproject/media/'
STATIC_URL = '/exampleproject/static/'

Of course you can create a custom setting to replicate this or to make the app work without a subpath as well, I believe this is a better solution than FORCE_SCRIPT_NAME because in that case I found we need to update the Django URLs anyways.

like image 155
Edison Arango Avatar answered Oct 11 '22 14:10

Edison Arango


I found here that one needs to add the following setting to Django's configuration in settings.py:

FORCE_SCRIPT_NAME = '/exampleproject'

This seems to rewrite all paths for nested resources.

like image 25
JJD Avatar answered Oct 11 '22 14:10

JJD