How to setup Django with Uwsgi and Nginx on Ubuntu 16.04

How to setup Django with Uwsgi and Nginx on Ubuntu 16.04

In this guide we will show you how to setup Django with Uwsgi and Nginx on Ubuntu 16.04. It is difficult and time-consuming to setup your server everytime. As Django is one of the best tools in its field due to its speed, scalability, and security. We thought that being said, we are going to install Django with Uwsgi and Nginx on Ubuntu 16.04 using a few methods and get your server up and running


  • Ubuntu 16.04 server
  • Root privileges/ sudo privileges

Ubuntu Repositories :

Login to the server by means of SSH and how about we get all the required stuff introduced:

ssh ubuntu@your-aws-example open ip - I key.pem 
cd ~ 

After login to your server through ssh run the beneath commands:

sudo apt-get update
sudo apt-get install python-dev
sudo apt-get install python-pip

It is a smart thought to work with a virtual domain. To make condition you pursue beneath steps:

mkdir our-projectname
cd our-projectname
pip install virtualenv

We should begin the virtualenv and enter it.

virtualenv venv
source venv/bin/activate

Django packages 

With your virtual condition dynamic, install Django with the local instance of pip by composing

pip install django startproject project_name

To check if it installed successfully, we have to do a runserver on port 8000

cd project_name
python runserver

Now in the event that you can get to you django undertaking utilizing your server IP, http://IPAddress:8080 your Django project should load up.

Configuring Uwsgi :

Django project keeps running inside the virtualenv. We need Uwsgi to serve django to the web rather than the lightweight improvement server, so we just ran utilizing runserver command. On the off chance that the idea of running the runserver command on a screen passes your brain, drop it.

Run the underneath command to stop your task and leave the virtualenv
Deactivate your virtualenv:


Presently install uwsgi system-wide on the grounds that, we’ll be running the server from the root client

sudo pip install uwsgi

Now run your project using uwsgi.  This command does the same thing a runserver would do



uwsgi - http :8000 - home/home/ubuntu/our-venture/venv - chdir/home/ubuntu/our-venture/projectname - w projectname.wsgi 

Presently in the event that you can get to you django undertaking utilizing your server IP, http://IPAddress:8080 your Django task should load up

Presently on the off chance that you can get to you django undertaking utilizing your server IP, http://IPAddress:8080 your Django venture should load up

We have to run this in the ‘foundation (run it and screen) so we will accomplish that next

The manner in which we will do it is by utilizing Ubuntu’s systemd, which gets pid 1 and this is completely bolstered for variants 15.04 and past. We will give it a chance to initialise our uwsgi procedure.

To store our config alternatives, we have to make an ‘ini’ document which will contain all the uwsgi config subtleties

sudo mkdir /etc/uwsgi/sites
sudo vim /etc/uwsgi/sites/projectname.ini

We’ll load the file with the config details.


          chdir = /home/ubuntu/our-project/hello #same as above
          home = /home/ubuntu/our-project/venv #same as above
          module = hello.wsgi:application #same as above
          master = true
          processes = 5 #more processes, more computing power
          socket = /run/uwsgi/hello.sock #SOCKET_LOC
          chown-socket = ubuntu:www-data #user and user's group
          chmod-socket = 660
          vacuum = true #delete the socket after process ends
          harakiri = 30 #respawn the process if it takes more than 30 secs

Save the file

We didn’t specify any port like 8000 as we did previously. We will defeat this through an attachment record rather than a port as this is progressively ideal. There is no distinction, just that whatever solicitations were steered to port 8000, would now be required to go by means of the attachment record

Now we can test if this works by running the command:

uwsgi - ini/and so on/uwsgi/locales/projectname.ini 

If everything works fine, we can see several lines and status as 5 or some number of procedures have been produced.

we have to let systemd (Ubuntu’s administration director) to deal with this:

Ubuntu's SystemD - call-> Service we make - execute-> Uwsgi ini - run-> Our Django Project
sudo vim /etc/systemd/system/uwsgi.service

Next you can Paste the following into it

          Description=uWSGI Emperor service
          ExecStartPre=/bin/bash -c 'mkdir -p /run/uwsgi; chown ubuntu:www-data /run/uwsgi' #make the folder where we'll store our socket file and have the right user/group permissions
          ExecStart=/usr/local/bin/uwsgi --emperor /etc/uwsgi/sites #this the command to execute on start
          Restart=always #make sure the server is running

Save the file

What we glued is basic, the administration will execute this line everytime it comes up and ensure it is up.

The head mode checks a specific envelope (for our situation, destinations) for .ini records and flames every one of them (our hello.ini is staying there) making it helpful in the event that we have various sites.

/usr/local/bin/uwsgi --emperor /etc/uwsgi/sites

Now let’s tell the systemd to run our service.

sudo systemctl restart uwsgi

If you want to make sure, you could do a top and see the number of processes (search for uwsgi) you wanted to spawn + 1

So now uwsgi is running. But we need to get it to appear when an HTTP request comes in. For that, we’re going to use Nginx.

Let’s install Nginx.

sudo apt-get install nginx
sudo service nginx start

If you hit the http://IPAddress you will see a Nginx welcome page. This is because Nginx is listening to port 80 according to its default configuration

Nginx has two directories, sites-available and sites-enabled. Nginx looks for all conf files in the sites-enabled folder and configures the server according to it.

sudo vim /etc/nginx/sites-available/projectname

You have to paste the following into it.

server {
    listen 80;
    server_name your-ec2-public-ip-address(if you don't have a domain);
    location = /favicon.ico { access_log off; log_not_found off; }
    client_max_body_size 20M;
    client_max_body_size 20M;
    location / {
        include         uwsgi_params;
        uwsgi_pass      unix:/run/uwsgi/hello.sock; #SAME as #SOCKET_LOC in the hello.ini


You can let server_name be a subdomain or multiple domains where you want to serve the website. The uwsgi_pass must point to the socket file we had our uwsgi ini file create. You can configure the Nginx conf far more and add a lot of things

We have to add this to sites-enabled directory, in order to be picked up by Nginx.

We can create a symlink to the file.

sudo ln -s /etc/nginx/sites-available/hello /etc/nginx/sites-enabled/

Now restart nginx and you’re all set.

sudo service nginx restart

Domain configuration

This is fairly straightforward. You need to add a simple record to your DNS records

Django configuration

During the configuration you will run into a 400 or 502 errors while trying to serve.

if you’re running with DEBUG = False and have not set ALLOWED_HOSTS in settings.

To allow those domains you have to allow hosts configured. You can allow everything,

ALLOWED_HOST = ['*'] #INCASE you want allow every host but this may turn out to be unsafe

Or allow the domains we configured in the nginx conf,

ALLOWED_HOST = ['','','IPAddress']

Finally, we’re live with our django site.

Hope you liked it and if you need any assistance on setting up Django with Uwsgi and Nginx on Ubuntu 16.04. Contact us.

To get glimpses of our activities follow us on: Twitter , Facebook