Moving Django to a subpath + Nginx + gunicorn (upd. 18.11.21)

upd. I forgot to include the most important line in the Nginx config. Sorry for that. but it does not work for me anymore. I am confused but I am postponing this for a few days to finish top priority tasks.

Super easy, super fun. Let’s base it on this great guide from Digital Ocean.

Say, the subpath you want is /secret/ 👀.

Add it to Nginx config:

server {
    listen 80;
    server_name server_domain_or_IP;

    location /secret/static/ {
        root /home/sammy/myprojectdir;
    }

    location /secret/ {
        rewrite /api(.*) $1 break;   # !!!!!!!!!!!!!! VERY IMPORTANT
        include proxy_params;
        proxy_pass http://unix:/run/gunicorn.sock;
    }
}

Then, things we will change in settings.py:

  • in Nginx root means that in the directory it will look for a secret/static/ directory. But now you only have a regular static/.
  • Currently your Django generated static links are all example.com/static, we will change that too.

Your new settings variables will be something like this:

STATIC_URL = '/secret/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'secret/static/'

MEDIA_URL = '/secret/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'secret/media/'
FORCE_SCRIPT_NAME = 'secret'

That’s it. Go check all absolute paths that you wrote down in your project and you are good.

www not working

Before you spend hours of working on Nginx config etc., check your domain’s DNS records.

You need to have a record resembling this:

Type: CNAME

Hostname/Name: http://www.your.website

Value: your.website

TTL (seconds): 3600

And in Nginx you need to capture http://www.your.website (port 80) and redirect it to https://your.website (port 443). Something like this:

server {
    listen 80;
    
    server_name www.your.website
    return 301 https://your.website$request_uri;
}