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

[Note] [Lifestyle] FireFox on Linux + Django + Nginx = 499 ERROR omfg

I spent 6 hours today in Nginx configurations and logs, I learnt so much about Nginx and devops process. And in the end it was all because FireFox browser (I use desktop Ubuntu on my laptop) refused to connect to the server and get the sweet HTML pages I tried to serve it.

In particular, when I renounced attempts to serve HTML pages with explicitly stated location tags and launched my good old trusted Django and it STILL didn’t work (I got 499/403 in the access.log and 404 in the browser), I came to thinking something evil is going on here. It was an unexpected, and a bad one.

The moment I opened it in Google Chrome and it worked, dudes, if I was standing, I would fall that moment on my butt.

I immediately wrote to my Python friends "screw web, I will do webcam now". But, it was a rushed thought I soon gave up. Thankfully, I did not write that to my boss.