How To Set Up Django with uWSGI, PostgreSQL and Nginx on Ubuntu 20.04

Louis SanchezApril 18th 2021, 6:19

We will install Django and all the components that are needed for Nginx and Django to be able to communicate.

Install the Packages

Step 1 : Install the Packages from the Ubuntu repositories

sudo apt-get update
sudo apt-get install python3-pip python3-dev libpq-dev postgresql postgresql-contrib nginx

Setting up Django

Step 2 : Upgrade pip and install the package by typing

sudo -H pip3 install --upgrade pip
sudo -H pip3 install virtualenv

Step 3 : Create a new Django Project

mkdir /var/www/myproject
cd /var/www/myproject
virtualenv env
source env/bin/activate
pip install django psycopg2 uwsgi
django-admin.py startproject myproject

Using PostgreSQL

Step 4 :Let's create a PostgreSQL user a new database with the following command:

sudo -u postgres psql
CREATE DATABASE myproject;
CREATE USER myproject WITH PASSWORD 'password';
GRANT ALL PRIVILEGES ON DATABASE myproject TO myproject;
\q

Step 5 : Then, edit the settings.py file and modify the DATABASES setting to make it look as follows:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'myproject',
        'USER': 'myproject',
        'PASSWORD': 'password',
        'HOST': 'localhost',
        'PORT': '',
    }
}

Step 6 : The new database is empty. Run the following command to apply all database migrations:

python3 manage.py migrate

Step 7 : Finally, create a superuser with the following command:

python3 manage.py createsuperuser

Test your project

Step 8 : Edit the settings file settings.py of your project and change the ALLOWED_HOSTS setting, as follows:

ALLOWED_HOSTS = ['*']

Step 9 : you can test our your project by starting up the Django development server with this command:

python3 manage.py runserver 0.0.0.0:8080

Step 10 : To see the result, we must open our browser and enter the following URL: http://{domin_or_ip}:8080

Step 11 : hit CTRL-C in the terminal window to shut down the development server.

Configuring uWSGI

Step 12 : You can run uWSGI from the command line. Open the shell and run the following command:

uwsgi --module=myproject.wsgi:application --socket 0.0.0.0:8080 --protocol=http

Step 13 : uWSGI allows you to define a custom configuration in a .ini file. This is more convenient than passing options through the command line. Create the following file structure inside the global myproject/uwsgi.ini directory:

[uwsgi]
# variables
projectname = myproject
base = /var/www/myproject
# configuration
master = true
virtualenv = %(base)/env
pythonpath = %(base)/myproject
env = DJANGO_SETTINGS_MODULE=%(projectname).settings
module = %(projectname).wsgi:application
socket = /tmp/%(projectname).sock
chmod-socket = 666

Step 14 : Now, you can run uWSGI with your custom configuration using this command:

uwsgi --ini uwsgi.ini

You will not be able to access your uWSGI instance from your browser now, since it's running through a socket. Let's complete the production environment.

Configuring NGINX

Step 15 : For running this Django site, you will need to add the following configuration

upstream myproject {
    server      unix:///tmp/myproject.sock;
}
server {
    listen       80;
    server_name  _;
    
    location / {
        include      /etc/nginx/uwsgi_params;
        uwsgi_pass   myproject;
    }
    location /media  {
        alias /var/www/myproject/myproject/myproject/media;
    }

    location /static {
        alias /var/www/myproject/myproject/myproject/static;
    }
}

Step 16 : To run uWSGI in the background, run the following:

uwsgi --ini uwsgi.ini &

Step 17 : Reload NGINX with the following command:

sudo service nginx reload

Deploying static files

Step 18 : First of all you have to edit myproject/settings.py adding:

import os

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

Step 19 : And then run

mkdir myproject/static
python3 manage.py collectstatic

Step 20 : Open {domin_or_ip}/admin in your browser. You should see the following screen:

Step 21 : Edit the settings.py

DEBUG = False
ALLOWED_HOSTS = ['yourdomin.com', 'www.yourdomin.com']