Open In App

How to install Django with NGINX, Gunicorn, and PostgreSQL on Ubuntu?

Improve
Improve
Like Article
Like
Save
Share
Report

This article describes how to install and configure Django with PostgreSQL, Gunicorn, and Nginx on your Ubuntu machine. First, let’s look at an overview of all the tools we use. Django is a robust, free, open-source, Python-based web framework that follows the MVT (Model-Template-View) architectural pattern. Though it includes an integrated development server for testing projects on your local system, however, using the development server for production is not recommended as it is not intended for this purpose. For this reason, we need a more robust and secure web server like Gunicorn that connects to Python applications via a WSGI interface. Nginx is a web server used as a reverse proxy with Gunicorn.

Installing required packages

The following command will install Python3, pip package installer, Nginx, and PostgreSQL on the Ubuntu machine,

# sudo apt install python3 python3-pip nginx postgresql postgresql-contrib

 

Configure PostgreSQL:

Now let’s configure PostgreSQL  to work with Django, to interact with Postgres we need to use its interactive shell prompt which we can activate as follow,

# sudo -u postgres psql

Output:

 

You can notice the change in the prompt, now we can do the configuration with Postgres which is creating a database and a user for the database.

postgres=# CREATE DATABASE demo;

postgres=# CREATE USER demouser WITH PASSWORD ‘12345678’;

postgres=# ALTER ROLE demouser SET client_encoding TO ‘utf8’;

postgres=# ALTER ROLE demouser SET default_transaction_isolation TO ‘read committed’;

postgres=# ALTER ROLE demouser SET timezone TO ‘UTC’;

postgres=# GRANT ALL PRIVILEGES ON DATABASE demo TO demouser;

Output:

 

As you can see above a database is created successfully along with a user and it is granted all required privileges. Now we are done with the Postgres setup let’s exit it,

# \q

Output:

 

Setup a development environment

First, let us configure the virtual environment, this step can be skipped but it is always a good idea to use a dedicated development environment for each project, this can be achieved using a python virtual environment.

To create one just run the following commands:

# mkdir python_web_app; cd python_web_app

Output:

 

This will create a dedicated folder for the project, you can name it anything you want and cd (change directory) to go into your newly created directory then run the following command that will create a virtual environment for your project.

# python3 -m venv venv
# ls

Output:

 

Now let’s activate the virtual environment and start using it.

# source venv/bin/activate

Output:

 

By now you will have a virtual environment ready to be used, so let’s install Django, Gunicorn, and Postgres adapter. 

# pip install django gunicorn psycopg2-binary

Creating and Configuring Django Project

Now that the development environment is configured we can start a Django project. Let’s create one by running the following commands.

# django-admin startproject demo_project .

The above command just created the Django default starter project, now we need to do a few tweaks in the settings.py file to allow the client access to the Django instance and also connect it with Postgres.

# nano settings.py

First, start by locating the ALLOWED_HOSTS directive, this defines a list of the server’s addresses or domain names that may be used to connect to the Django instance.

 

Now let’s connect it to Postgres Database.

 

All done let’s migrate changes to the database and we are good to go.

# python3 manage.py makemigrations
# python3 manage.py migrate

Output:

 

now run the following command

# python3 manage.py runserver

Output:

 

If you see output similar to the image, you’ve successfully created a live Django project on your localhost on port 8000.

Configure Gunicorn to serve the project

In the previous step, we used the built-in Django development server to run our project, but this is not a deployment server intended to be used only during development. Let’s run the Django project with Gunicorn using the following command:

# gunicorn –bind 0.0.0.0:8000 demo_project.wsgi

Output:

 

The above command binds Gunicorn with the WSGI interface of the Django project, make sure you have allowed the inbound ports in the firewall.

 

Now everything is up and working, let us deploy the Django web app.

Creating system Socket and Service files for Gunicorn

Now that you’ve tested that Gunicorn with your Django application, you should implement a more robust way of starting and stopping the application server. To accomplish this, we will create systemd service and socket files, by running the following commands.

# sudo nano /etc/systemd/system/gunicorn.socket

This will open the system socket file for Gunicorn with sudo privileges, and add the following stuff to the file, which creates a [Unit] section to describe the socket, a [Socket] section to define the socket location, and a [Install] section to make sure the socket is created at the right time, once done just save and close the file.

[Unit]
Description=gunicorn socket

[Socket]
ListenStream=/run/gunicorn.sock

[Install]
WantedBy=sockets.target

 

# sudo nano /etc/systemd/system/gunicorn.service

Now, let’s create and open a systemd service file for Gunicorn (the filename should match the socket filename) and add the following content to the file. It should look something like this.

 

As you can see It contains 3 sections :

  • [Unit]: This is used to specify metadata and dependencies.
  • [Service]: it specifies the user and group that you want the process to run under, also giving group ownership to the www-data group so that Nginx can communicate with Gunicorn.  
  • [Install]: This will tell systemd what to link this service to if you enable it to start at boot.

Enabling and checking socket and service files for Gunicorn

The following commands will start running the Gunicorn socket service and will enable it to start automatically on boot.

# sudo systemctl start gunicorn.socket
# sudo systemctl enable gunicorn.socket

Output:

 

Check the status of the Gunicorn process to find out whether it was able to start

# sudo systemctl status gunicorn

Output:

 

If something goes wrong you can see the logs for Gunicorn process by running the following command:

# sudo journalctl -u gunicorn.socket

Configure Nginx proxy

At this point, the Gunicorn setup is complete. Next, we need to set up an Nginx server as a proxy to handle all HTTP traffic and forward it to Gunicorn for processing. First, create a new server block in the directory available to your Nginx site.

# sudo nano /etc/nginx/sites-available/demo_project

 

server {

   listen 80;

   server_name server_domain_or_IP;

   location = /favicon.ico { access_log off; log_not_found off; }

   location /static/ {

       root <project path>;

   }

   location / {

       include proxy_params;

       proxy_pass http://unix:/run/gunicorn.sock;

   }

}

As you can see, we have opened a server block in which we have specified that his block should listen on port 80 and that it should respond to the domain name you have provided.

In the location block, I told it to ignore problems finding my favorite icon and mapped the Nginx static path to the Django project static path.

When finished, save and close the file. Now you can enable the file by linking it to the site-enabled directory.

# sudo ln -s /etc/nginx/sites-available/demo_project /etc/nginx/sites-enabled

All done now just test the Nginx file for any syntax errors and restart the Nginx daemon.

# sudo nginx -t

Output:

 



Last Updated : 21 Feb, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads