Skip to main content

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.

Updated 4 min readMarkdown
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. 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 yourdomain.com

  • hostname # check the hostname

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

    • host_ip_address yourdomain.com

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
SpongebobDatabaseGIF.gif

6. Configure Postgresql

sudo -u postgres psql
CREATE DATABASE my_db;
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';
GRANT ALL PRIVILEGES ON DATABASE my_db TO db_usr;
MiniMansionsGIF.gif

7. Configure Project

python3.8 -m venv env
pip install --upgrade pip
pip install -r requirements.txt
python manage.py 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.

[Unit]
Description=gunicorn socket

[Socket]
ListenStream=/run/gunicorn.sock

[Install]
WantedBy=sockets.target

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.

[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target

[Service]
User=saurav
Group=www-data
WorkingDirectory=/home/saurav/trends
EnvironmentFile=/home/saurav/trends/.base.env
ExecStart=/home/saurav/trends/env/bin/gunicorn \
        --access-logfile - \
        --workers 3 \
        --bind unix:/run/gunicorn.sock \
        trends.wsgi:application

[Install]
WantedBy=multi-user.target

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;
    server_name 139.84.163.233;

    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
LetsFigureThisOutSolveGIF.gif

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

https://www.digitalocean.com/community/tutorials/how-to-set-up-django-with-postgres-nginx-and-gunicorn-on-ubuntu

DudeImJustLearningStanMarshGIF.gif

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.


ox

Tired of doing all this by hand? ox deploys your repo to your own Ubuntu server for you, with systemd and Caddy instead of hand-written Gunicorn and Nginx files. No Docker, no config maze. Try deploywithox.com

About the author

  • Hi, I鈥檓 a self-taught backend developer with 3+ years of experience, currently working at a tech startup based in The Bahamas. I mostly work with Python and Django, building APIs, designing database models, and improving performance when needed. I enjoy learning new tools and technologies as projects require.

No comments yet. Be the first to comment.