Deploy Django App over Ubuntu VPS with Gunicorn + Nginix + PostgreSQL

Deploy Django App over Ubuntu VPS with Gunicorn + Nginix + PostgreSQL

In this tutorial, we will deploy a Django app over Ubuntu VPS with Gunicorn + Nginix + PostgreSQL. We are going to use Vultr VPS for this tutorial.

In this tutorial, we will deploy a Django app over Ubuntu VPS with Gunicorn + Nginix. We are going to use Vultr VPS for this tutorial. You can use any other VPS provider as well.

1. Create a new user

  • adduser yourusername

  • usermod -aG sudo yourusername

  • logout and login with your new user

2. Set the HostName

  • hostnamectl set-hostname

  • hostname # check the hostname

  • sudo nano /etc/hosts # add the hostname to the hosts file

    • host_ip_address

3. Passwordless login

  • on the local environment:

    • generate your ssh key if you don't have one

    • copy the public key

  • on the remote environment:

    • create a .ssh folder

    • In that folder, create a file named authorized_keys like this .ssh/authorized_keys

    • paste the public key into the file

    • each key should be in a separate line. If you have multiple keys, you can paste them all into the file to allow multiple users to log in without a password

    • chmod 700 .ssh

    • chmod 600 .ssh/authorized_keys

    • sudo nano /etc/ssh/sshd_config # change PermitRootLogin & PasswordAuthentication to no

    • sudo service ssh restart

4. Install & configure UFW

sudo apt install ufw
sudo ufw allow ssh
sudo ufw enable
sudo ufw status

5. Install Dependencies

git clone yourproject
sudo apt update
sudo apt install python3.8 python3-pip python3.8-venv python3.8-dev build-essential libpq-dev python3-dev postgresql postgresql-contrib nginx curl


6. Configure Postgresql

sudo -u postgres psql
CREATE USER db_usr WITH ENCRYPTED PASSWORD 'some_secure_pass@pass';
ALTER ROLE db_usr SET client_encoding TO 'utf8';
ALTER ROLE db_usr SET default_transaction_isolation TO 'read committed';


7. Configure Project

python3.8 -m venv env
pip install --upgrade pip
pip install -r requirements.txt
python migrate

8. Configure Gunicorn

sudo apt install gunicorn
sudo nano /etc/systemd/system/gunicorn.socket

Below is the content, you need to put in this file.

Description=gunicorn socket



we also need a gunicorn service file. so enter to this command to create & edit that service file.

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

add the below content to this file.

Description=gunicorn daemon

ExecStart=/home/saurav/trends/env/bin/gunicorn \
        --access-logfile - \
        --workers 3 \
        --bind unix:/run/gunicorn.sock \


Now Run below commands -

sudo systemctl start gunicorn.socket
sudo systemctl enable gunicorn.socket
sudo systemctl status gunicorn.socket
file /run/gunicorn.sock

Note: If you get an error like this: - debug it with sudo journalctl -u gunicorn.socket

8. Configure Nginix

sudo nano /etc/nginx/sites-available/trends

put below content in this file.

server {
    listen 8000;

    location = /favicon.ico { access_log off; log_not_found off; }
    location /static/ {
        root /home/saurav/trends;

    location / {
        include proxy_params;
        proxy_pass http://unix:/run/gunicorn.sock;

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

sudo nginx -t

sudo systemctl restart nginx

sudo ufw allow 'Nginx Full'

UnamusedCatGIF (2).gif

Congratulations 🎉🎊 if all steps are executed successfully, then your website should be live now.

Note: Some commands to reload/modify/debug services:

sudo systemctl restart gunicorn  # restart gunicorn
sudo systemctl daemon-reload  
sudo tail -F /var/log/nginx/error.log  # check nginix error logs
sudo systemctl status postgresql  # start your psql db server
sudo systemctl restart gunicorn.socket gunicorn.service  # restart gunicorn


If you are still having problem then check this great article by Digital Ocean.


Disclaimer - I am not an expert & still learning. So, there may be some things which i may missed out or may be wrongly explained. As I got any comment about mistakes or figured out somewhere then i will correct it in blog.

Did you find this article valuable?

Support Saurav Sharma by becoming a sponsor. Any amount is appreciated!