Deploy Django using Postgres, Nginx in digital ocean ubuntu droplet

Hemanth S P
DjangoTube:
Published in
6 min readJan 8, 2022
Deploy Django using Postgres, Nginx in digital ocean
Photo by Kirill Sh on Unsplash

Hi, To deploy any web application there are multiple ways however in this article I will show the simplest and traditional way of deploying Django to digital ocean droplets.

Step 1: Digital Ocean sign in or sign up

sign in or sign up(if you signing up for the first time then use this referral link) to the digital ocean account.

Step 2: Create Droplet

Click on the create button to create one droplet on the top right of the screen, it is shown in the below image

Click on the Droplets option from the dropdown

Step 3: configure droplet

configure your droplet based on your customer, for the demonstration purpose I am going to select ubuntu

select ubuntu

choose a plan

choose a plan

choose the location

location

choose the ssh or password

ssh or password

Click on the create button

create button

and it will take several minutes to create a droplet for you and once done the page is automatically redirected to your available droplet screen so the final droplet you can view like this.

final droplet image

Step 4: Access the created droplet

you can access the created droplet by using a terminal(from your local pc) or by clicking the console link as shown in the above photo at the top right.

Step 5: push the code to the remote server(droplet).

I have a demo Django project and I will push it to GitHub and then I will pull it in the remote server.

Step 6: log in to your droplet

open the terminal and type as below

$ ssh root@your ipv4 address
for example
$ ssh root@143.244.140.67

and if it is the first time type as yes.

Enter the password to login

login into the droplet or server

and we need to pull code in the destination folder this path is in

$ cd /var/www/

by default, the www folder won't be inside the var folder so to create the www folder we must install Nginx

$ sudo apt-get update$ sudo apt-get install nginx# Verify the Installation
$ nginx -v
you can start and verify it by running:
$ sudo systemctl start nginx
$ sudo systemctl status nginx

and move inside the

 $ cd /var/www/

pull code from git hub repository using git clone

# for examplegit clone https://github.com/hemanth-sp/django-demo-app-with-postgress.git

once done, then go inside the project folder

root@ubuntu-s-1vcpu-1gb-blr1–01:/var/www# cd django-demo-app-with-postgress/

create a virtual environment in the project folder itself or wherever you want, I am using the python 3.8 version so I will create a virtual one like this

$ python3.8 -m venv venv# and if you got an error then install python3.8
$ apt install python3.8-venv

do ls to check everything one place

root@ubuntu-s-1vcpu-1gb-blr1–01:/var/www/django-demo-app-with-postgress# ls
dashboard db.sqlite3 django_awesome manage.py requirements.txt static templates venv

now activate virtual and install requirements from requirements.txt

root@ubuntu-–01:/var/www/django-demo-app-with-postgress# source venv/bin/activate
(venv) root@ubuntu-–01:/var/www/django-demo-app-with-postgress#
(venv) root@ubuntu--01:/var/www/django-demo-app-with-postgress# pip3 install -r requirements.txt

while installing requirements if got an error from psycopg2 then use the below commands to install the additional dependencies of python

sudo apt install libpq-dev python3-dev
sudo apt install build-essential
sudo apt-get install python3.8-dev

Step 7: Create a database

# install postgresql in server
# or use postgresql-11, postgresql-12 or install latestest version
$ sudo apt-get -y install postgresql# Connect to PostgreSQL
lr1-01:/var/www/django-demo-app-with-postgress# su - postgres
postgres@ubuntu-s-1vcpu-1gb-blr1-01:~$ psql# execute this commond command to create db and create and alter userpostgres=# create user django;create database demodb;alter role django with password 'djangopassword';grant all privileges on database demodb to django;alter database demodb owner to django;

Results from Postgres will be like

CREATE ROLE
CREATE DATABASE
ALTER ROLE
GRANT
ALTER DATABASE

type exit to close the PostgreSQL.

Step 8: do migrate

(venv) root@ubuntu-s-1vcpu-1gb-blr1–01:/var/www/django-demo-app-with-postgress# python manage.py migrate

Step 9: set static and media root

STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'whole-static')
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'whole-media')

and STATICFILES_DIRS used to collect the static files from the static folder inside the project folder

STATICFILES_DIRS = [os.path.join(BASE_DIR, ‘static’),]

Create folders

(venv) root@ubuntu-:/var/www/django-demo-app-with-postgress# mkdir whole-static
(venv) root@ubuntu:/var/www/django-demo-app-with-postgress# mkdir whole-media

type below commands to collect the static

$ python manage.py collectstatic1970 static files copied to ‘/var/www/django-demo-app-with-postgress/whole-static’

Step 10: Configure Nginx

navigate to

cd /etc/nginx/sites-available/

delete default file because of no use in that and also remove default in the sites-enabled folder.

rm default

create new called web

(venv) root@ubuntu-s-1vcpu-1gb-blr1–01:/etc/nginx/sites-available# touch web

and edit web using vi or nano.

upstream app_server {
server unix:/var/www/django-demo-app-with-postgress/web.sock fail_timeout=0;
}
server {

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

server_name 143.244.140.67;

# add here the ip address of your server

keepalive_timeout 5;
client_max_body_size 4G;

access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;


location /static/ {
alias /var/www/django-demo-app-with-postgress/whole-static/;
}

location /media/ {
alias /var/www/django-demo-app-with-postgress/whole-media/;
}
# checks for static file, if not found proxy to app

location / {
try_files $uri @proxy_to_app;
}
location @proxy_to_app {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
#proxy_pass http://app_server;
if (!-f $request_filename) {
proxy_pass http://app_server;
break;
}
}
}

and save this, please have a look at every line of the file because the project path is important then make a soft link.

(venv) root@ubuntu-s-1vcpu-1gb-blr1–01:~# ln -s /etc/nginx/sites-available/web /etc/nginx/sites-enabled/web

verify Nginx configuration is working or not!

(venv) root@ubuntu-s-1vcpu-1gb-blr1–01:/etc/nginx/sites-enabled# nginx -t

restart the Nginx

sudo systemctl restart nginx

Step 11: Configure gunicorn

install gunicorn web server inside the virtual because it is required for the supervisor to run.

(venv) root@ubuntu-s-1vcpu-1gb-blr1–01:~# pip3 install gunicorn

Step 12: Configure supervisord

Install supervisor by entering the following commands in the terminal

sudo apt update
sudo apt install supervisor

navigate to

cd /etc/supervisor/conf.d/(venv) root@ubuntu-s-1vcpu-1gb-blr1–01:/etc/supervisor/conf.d# touch web.conf
(venv) root@ubuntu-s-1vcpu-1gb-blr1-01:/etc/supervisor/conf.d# nano web.conf

and paste the following code inside the web.conf file

[program:django-demo]
command=/var/www/django-demo-app-with-postgress/venv/bin/gunicorn — workers 3 — bind unix:/var/www/django-demo-app-with-postgress/web.sock django_awesome.wsgi
directory=/var/www/django-demo-app-with-postgress
autostart=true
autorestart=true
stderr_logfile=/var/log/gunicorn_supervisor.out.log
stdout_logfile=/var/log/gunicorn_supervisor.log
user=root
redirect_stderr=true
environment=LANG=en_US.UTF-8,LC_ALL=en_US.UTF-8

Update the superviosr

supervisorctl reread

django-demo: available

supervisorctl update

django-demo: added process group

supervisorctl status

django-demo STARTING

supervisorctl restart django-demo

navigate to create log files for the supervisor

cd /var/log(venv) root@ubuntu-s-1vcpu-1gb-blr1–01:/var/log# touch gunicorn_supervisor.out.log
(venv) root@ubuntu-s-1vcpu-1gb-blr1–01:/var/log# touch gunicorn_supervisor.log
final deployment image

So next if new code push to Github then you have to do this much only

  1. ssh root@ipv4 address(login to server)
  2. cd /var/www/django-demo-app-with-postgress/ (go to folder)
  3. git pull (to get the latest code)
  4. source venv/bin/activate (activate virtual)
  5. migrate (if any model change)
  6. collectstatic (if any static file changes)
  7. supervisorctl status ( to check the status of the service)
  8. supervisorctl restart django-demo (to restart services and important)

Conclusion

This article simply shows the way of deploying the Django code in the ubuntu server however still adding domain and enabling SSL certificate remaining, and make sure to off debug while deploying and please take a moment on Django website to find out more on security instructions before deploying the code

                  python manage.py check — deploy

--

--