DEV Community

Cover image for Django in Production - II
Idiomatic Programmers
Idiomatic Programmers

Posted on • Originally published at idiomaticprogrammers.com on

Django in Production - II

In the last post, we learnt how to make use of Gunicorn to run our Django application, and use Whitenoise to serve static files. Today, we are going to learn how to configure a reverse proxy in front of gunicorn to serve our website on port 80, and also use it as web server to serve our static files instead of using Whitenoise.

NGINX Installation

If you're using Ubuntu, run the following commands:

sudo apt-get update
sudo apt-get install nginx
Enter fullscreen mode Exit fullscreen mode

Now you can check the status of nginx by running command:

sudo systemctl status nginx
Enter fullscreen mode Exit fullscreen mode

or

sudo service nginx status
Enter fullscreen mode Exit fullscreen mode

based on how your system is setup.

NGINX Configuration

So, for running NGINX you'll need to write configuration files. They're stored in the /etc/nginx/sites-available/ directory.

Let's first go into that directory by running:

cd /etc/nginx/sites-available/
Enter fullscreen mode Exit fullscreen mode

Now let's create a file by doing:

sudo touch django.conf
Enter fullscreen mode Exit fullscreen mode

And now let's open the file in the editor by doing:

sudo nano django.conf
Enter fullscreen mode Exit fullscreen mode

Hint : We need to use sudo here because this directory is present in root and not inside our home directory.

Then paste the below config inside it.

server {                 
   server_name server_domain_or_ip;

   location / {
      include proxy_params;
      proxy_pass http://localhost:8000;
    }
}
Enter fullscreen mode Exit fullscreen mode

In place of server_domain_or_ip you'll put either IP address or the domain of your website.

So NGINX uses this concept where you can have multiple configuration files as backup stored under /etc/nginx/sites-available/. But the active ones are present under /etc/nginx/sites-enabled/

So, you put your configuration files under sites-available and then create a soft symlink to that file inside sites-enabled

So let's create the symlink for this file under /etc/nginx/sites-enabled/.

To do that, run the following command:

cd sites-enabled
sudo ln -s /etc/nginx/sites-available/django.conf .
Enter fullscreen mode Exit fullscreen mode

This will create the symlink of our config file under sites-enabled.

Now for our changes to come in effect, we'll need to instruct NGINX to read our config file once again and restart the server, we do this by running:

sudo systemctl restart nginx
Enter fullscreen mode Exit fullscreen mode

or

sudo service nginx restart
Enter fullscreen mode Exit fullscreen mode

Making our site secure

Right now, our site is being served at port 80, which means http, which isn't secure. But we want our website to be secure. So now let's install SSL certificate for our website using the certificate provided by Let's Encrypt. To do that, follow the steps below:

  1. Let's update the packages list to the latest version, before we install our dependencies by running:
sudo apt-get update
Enter fullscreen mode Exit fullscreen mode
  1. Now let's install our dependencies.
sudo apt-get install software-properties
Enter fullscreen mode Exit fullscreen mode
  1. Let's add the repository needed for installing the certificate generating utility, by running:
sudo add-apt-repository universe
sudo add-apt-repository ppa:certbot/certbot
Enter fullscreen mode Exit fullscreen mode
  1. Now we need to refresh our local packages list, by running:
sudo apt-get update
Enter fullscreen mode Exit fullscreen mode
  1. Let's finally install the needed packages by running:
sudo apt-get install certbot python3-certbot-nginx
Enter fullscreen mode Exit fullscreen mode
  1. Now we can create and configure ssl certificates for our nginx configuration:
sudo certbot --nginx
Enter fullscreen mode Exit fullscreen mode

When you run the last command, there'll be an interactive CLI program, that'll ask you for certain configuration specifics, one of them will be whether you want to redirect non secure traffic to https, then you should choose Yes.

If you aren't running Ubuntu on your server, then you can use this website to look for instructions for your own OS.

Serving Static Files using NGINX

Now that you have finally added NGINX to your stack, you can use it for serving your static files as well, as it can perform much better than the whitenoise alternative we discussed earlier.

First, we need to make changes to our Django settings.py file, add the below line inside it:

STATICFILES_STORAGE = "django.contrib.staticfiles.storage.ManifestStaticFilesStorage"
STATIC_ROOT = os.path.join(BASE_DIR, "staticfiles")
STATIC_URL = "/static/"
Enter fullscreen mode Exit fullscreen mode

Make sure, the above settings are not defined elsewhere in your settings.

Now go in your project root directory and create the folder staticfiles by typing the following in your terminal:

mkdir staticfiles
Enter fullscreen mode Exit fullscreen mode

If you have your own static files (CSS, JS etc.) used in your templates, then pass the path to files (in our case static) as follows:

STATICFILES_DIRS = [
    os.path.join(BASE_DIR, "static"),
]
Enter fullscreen mode Exit fullscreen mode

Now run the following command:

python manage.py collectstatic
Enter fullscreen mode Exit fullscreen mode

Now that we are done setting up our django project, let's configure NGINX to serve these files, go back to the nginx directory by typing the below line:

cd /etc/nginx/sites-available/
sudo nano django.conf
Enter fullscreen mode Exit fullscreen mode

Make the following changes to your config:

server {                 
   server_name server_domain_or_ip;

   location / {
      include proxy_params;
      proxy_pass http://localhost:8000;
   }

    # Below part is to be added for static files
    location /static/ {
        alias /home/ubuntu/path/to/django/project/staticfiles/;
        expires 365d;
        autoindex off;
    }

}
Enter fullscreen mode Exit fullscreen mode

Add the newly added part to your configuration, and make sure to replace /home/ubuntu/path/to/django/project/ with the actual path where your project is stored.

When you're done, restart the nginx by running:

sudo systemctl restart nginx
Enter fullscreen mode Exit fullscreen mode

or

sudo service nginx restart
Enter fullscreen mode Exit fullscreen mode

And we're done serving static files using NGINX.

In the next post, we are going to configure a process control system, which will ensure that our gunicorn worker remains up all the time, and starts automatically at boot time.

Top comments (0)