0% found this document useful (0 votes)
24 views

Deploy Django Website Using Nginx, Gunicorn, Postgres DB and Apply SSL

This document provides instructions for deploying a Django website on an Ubuntu server using Nginx, Gunicorn, PostgreSQL DB and SSL. It discusses prerequisites, installing packages, creating a Postgres user and database, setting up a Python virtual environment, creating and configuring the Django project, and configuring Nginx and Gunicorn. The steps allow one to deploy a Python/Django application on a server with SSL and use PostgreSQL as the database.

Uploaded by

cacho2013
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
24 views

Deploy Django Website Using Nginx, Gunicorn, Postgres DB and Apply SSL

This document provides instructions for deploying a Django website on an Ubuntu server using Nginx, Gunicorn, PostgreSQL DB and SSL. It discusses prerequisites, installing packages, creating a Postgres user and database, setting up a Python virtual environment, creating and configuring the Django project, and configuring Nginx and Gunicorn. The steps allow one to deploy a Python/Django application on a server with SSL and use PostgreSQL as the database.

Uploaded by

cacho2013
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 9

Deploy Django website using Nginx, Gunicorn, Postgres DB and apply SSL https://sleeksoft.in/deploy-django-website-in-ubuntu-server-using-nginx-gunicorn-and-wsgi-with-pos...

Introduction
Django is undoubtedly one of the most popular and powerful framework / MVC today. This is a high-level Python web framework. Many
popular and heavy websites like Instagram, Pinterest use django framework.

As a developer, I struggled initially on how to deploy a website in a Ubuntu server. After going through many tutorials, videos and how-to
guides over the internet I compiled following steps to deploy a django website / application on server.

Video demo on how to deploy django application

Deploy Django website in Ubuntu server with Nginx Gunicorn PostgreSQL DB and apply SSL | Sleeksoft

Prerequisites
You need to have following

• Server with minimum 1vCPU, 1GB RAM and 20GB SSD


• Ubuntu 20.04 OS
• SSH access
• PUTTY ready to access the console / terminal of your server
• You should have sudo permissions

Legend

1. example.com – You need to replace this with the domain name you use in your setup
2. sleekproject – This is project directory, you can name this according to your project requirements
3. sleekenv – This is virtual environment, you can name it as whatever you want to.
4. sleeksoft – This is our django project, you can name this based on your project title etc..

Section 1 : Installing required packages


Before we dive into installing required packages, we need to update and upgrade the server and existing packages to the latest version.

Copy
sudo apt update -y

Copy
sudo apt upgrade -y

Install all the required packages in one command.

Copy

1 de 9 13/6/2022 13:45
Deploy Django website using Nginx, Gunicorn, Postgres DB and apply SSL https://sleeksoft.in/deploy-django-website-in-ubuntu-server-using-nginx-gunicorn-and-wsgi-with-pos...

sudo apt install python3-pip python3-dev libpq-dev postgresql postgresql-contrib nginx curl file

List of packages installed are

• Pip (Python package installer)


• Python development �les
• PostgreSQL and Libraries
• Nginx web server
• CURL

Section 2 : Creating Postgres user and database


Run following command to enter into Postgres environment. By default when Postgres is installed, we will get an user called ‘postgres’
with administrative rights in PostgreSQL. We use this user to create Database and User account in postgres for our project.

Copy
sudo -u postgres psql

Create a database for our project

Copy
CREATE DATABASE sleeksoft;

Note: Every Postgres statement MUST end with a semi-colon

Create a database user for our project. Make sure to select a secure password.

Copy
CREATE USER sleekuser WITH PASSWORD 's133ks0ft';

Note: Here database user is ‘sleekuser’ and password is ‘s133ks0ft’

Set the default encoding to UTF-8, which is recommended by django

Copy
ALTER ROLE sleekuser SET client_encoding TO 'utf8';

Set the default transaction isolation scheme to ‘read committed’. This blocks the reads from uncommitted transactions.

Copy
ALTER ROLE sleekuser SET default_transaction_isolation TO 'read committed';

Set the default timezone to UTC. This is the default timezone our django project too will have.

Copy
ALTER ROLE sleekuser SET timezone TO 'UTC';

Now, give our database user ‘sleekuser’ to have all the privileges in the database ‘sleeksoft’.

Copy
GRANT ALL PRIVILEGES ON DATABASE sleeksoft TO sleekuser;

Now we have successfully created a database and a database user who has all the privileges over the database we created in the
PostgreSQL. Quit from Postgres environment.

Copy
\q

Section 3 : Creating Python Virtual Environment


Upgrade pip and install Python virtual environment.

Copy
sudo -H pip3 install --upgrade pip

Copy
sudo -H pip3 install virtualenv

Create a project folder where you can create virtual environment and install django, gunicorn etc.. for our project. In this tutorial, I am
going to create the project folder inside /home/ directory.

Copy
cd /home

2 de 9 13/6/2022 13:45
Deploy Django website using Nginx, Gunicorn, Postgres DB and apply SSL https://sleeksoft.in/deploy-django-website-in-ubuntu-server-using-nginx-gunicorn-and-wsgi-with-pos...

mkdir sleekproject

Navigate to the project folder / directory.

Copy
cd sleekproject/

Create virtual environment inside the project directory. I am naming the virutal environment as ‘sleekenv’.

Copy
virtualenv sleekenv

This will create a directory called ‘sleekenv‘ within ‘sleekproject‘ directory. Inside, it will install a local version of Python and a local
version of pip. We can use this to install and con�gure an isolated Python environment for our project. Before we install our project’s
Python requirements, we need to activate the virtual environment.

Copy
Copy
source sleekenv/bin/activate

The terminal prompt should change to indicate that you are now operating within a Python virtual environment. It will look something like
this

(sleekenv) root@host:/home/sleekproject#

With virtual environment activated, now we can install Django, Gunicorn and the PostgreSQL adapter (psycopg2) using pip. In virtual
environment we can just use pip instead of pip3 no matter if you are using Python version 3.

Copy
pip install django gunicorn psycopg2-binary pillow

We now have all the softwares we needed to start our Django project.

Section 4 : Creating and configuring django project


Create django project called ‘sleeksoft’

Copy
django-admin startproject sleeksoft

Now you will see a new directory ‘sleeksoft’ inside our project folder. So the whole path will be /home/sleekproject/sleeksoft. Now we
need to con�gure settings.py �le in ‘sleeksoft’ directory.

Open settings.py and add ALLOWED_HOSTS to have the localhost and domain name. Change ‘example.com’ to your domain name.

Copy
ALLOWED_HOSTS = ['example.com', 'localhost']

Note: Be sure to include localhost as one of the options since we will be using connections through a local Nginx server instance.

Update database details in settings.py. These settings will de�ne the link between our django project and the PostgreSQL database we
created. By default settings.py will have a Database details linking to SQLite, replace that with the following code.

Copy
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'sleeksoft',
'USER': 'sleekuser',
'PASSWORD': 's133ks0ft',
'HOST': 'localhost',
'PORT': '',
}
}

Add / Change setting indicating where the static �les should be placed. This is necessary so that Nginx can handle requests for these
�les. The following setting tells Django to place static �les in a directory called static in the base project directory.

Copy
STATIC_URL = '/static/'
STATIC_ROOT = BASE_DIR / 'static'

3 de 9 13/6/2022 13:45
Deploy Django website using Nginx, Gunicorn, Postgres DB and apply SSL https://sleeksoft.in/deploy-django-website-in-ubuntu-server-using-nginx-gunicorn-and-wsgi-with-pos...

Let’s make the initial migration, which will setup the database tables etc.. You need to be inside the django project we created to run
following commands /home/sleekproject/sleeksoft.

Copy
cd sleeksoft/

Copy
python3 manage.py makemigrations

Copy
python3 manage.py migrate

Now, create a superuser for our website.

Copy
python3 manage.py createsuperuser

You should enter username, email and password to create a superuser account. After this, lets do the collectstatic command which will
collect all the static �les in our website to /static/ folder. Remember we de�ned ‘/static/’ folder in settings.py.

Copy
python3 manage.py collectstatic

Create an exception for port 8000. So, we can test that django setup is installed properly.

Copy
sudo ufw allow 8000

Now, we can test our your project by starting up the Django development server with the following command

Copy
python3 manage.py runserver 0.0.0.0:8000

In the web browser, visit the server’s domain name or IP address followed by :8000. Here 8000 is a port number.

Copy
http://server_domain_or_IP:8000

If all setup is done properly, you should see following in the browser.

4 de 9 13/6/2022 13:45
Deploy Django website using Nginx, Gunicorn, Postgres DB and apply SSL https://sleeksoft.in/deploy-django-website-in-ubuntu-server-using-nginx-gunicorn-and-wsgi-with-pos...

We can login into the django admin by going to /admin/ from home page. There we can use the super user account we created in previous
steps. After exploring the Django admin, use CTRL-C in the terminal window to shut down the development server.

Bind Gunicorn with our project

Run following command to bind Gunicorn with our project.

Copy
gunicorn --bind 0.0.0.0:8000 sleeksoft.wsgi

This will start Gunicorn on the same interface that the Django development server was running on. We can go back and test the website
again. The only difference is we are not doing startserver command from Django, instead Gunicorn will take care of that.

Note: In some cases the admin interface will not have any styling applied since Gunicorn does not know how to �nd the static CSS
content responsible for this. We will con�gure that in Nginx.

After �nished testing, use CTRL-C in the terminal window to stop Gunicorn. We now �nished con�guring our Django application /
Website. We can quit from the virtual environment using the following command.

Copy
deactivate

The virtual environment indicator in the command prompt will be removed.

Section 5 : Creating systemd Socket and Service Files for Gunicorn


We have tested that Gunicorn can interact with our Django application, but we should implement an easy and ef�cient way of starting
and stopping the application server. To achieve this, we’ll make systemd service and socket �les for Gunicorn.

Create and open a systemd socket �le for Gunicorn in the following path.

Copy
sudo touch /etc/systemd/system/gunicorn.socket

5 de 9 13/6/2022 13:45
Deploy Django website using Nginx, Gunicorn, Postgres DB and apply SSL https://sleeksoft.in/deploy-django-website-in-ubuntu-server-using-nginx-gunicorn-and-wsgi-with-pos...

gunicorn.socket �le will be created in the above path, download via FTP and start adding the following code to it.

Copy
[Unit]
Description=gunicorn socket

[Socket]
ListenStream=/run/gunicorn.sock
# Our service won't need permissions for the socket, since it
# inherits the file descriptor by socket activation
# only the nginx daemon will need access to the socket
SocketUser=www-data
# Optionally restrict the socket permissions even more.
# SocketMode=600

[Install]
WantedBy=sockets.target

Save, close and upload the �le via FTP when you are �nished.

Next, create and open a systemd service �le for Gunicorn with sudo privileges. The service �lename should match the socket �lename
with the exception of the extension:

Copy
sudo touch /etc/systemd/system/gunicorn.service

gunicorn.service �le will be created in the above path, download via FTP and start adding the following code to it.

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

[Service]
Type=notify
# the specific user that our service will run as
User=root
# Group=someuser
# another option for an even more restricted service is
# DynamicUser=yes
# see http://0pointer.net/blog/dynamic-users-with-systemd.html
RuntimeDirectory=gunicorn
WorkingDirectory=/home/sleekproject/sleeksoft
ExecStart=/home/sleekproject/sleekenv/bin/gunicorn sleeksoft.wsgi
ExecReload=/bin/kill -s HUP $MAINPID
KillMode=mixed
TimeoutStopSec=5
PrivateTmp=true

[Install]
WantedBy=multi-user.target

Save, close and upload the �le via FTP when you are �nished.

Now, our systemd service �le is complete. We can now start and enable the Gunicorn socket. This will create the socket �le at
/run/gunicorn.sock now and at boot. When a connection is made to that socket, systemd will automatically start the gunicorn.service to
handle it.

Copy
sudo systemctl start gunicorn.socket

Copy
sudo systemctl enable gunicorn.socket

We can con�rm that the operation was successful by checking for the socket �le. Check the status of the process to �nd out whether it
was able to start:

6 de 9 13/6/2022 13:45
Deploy Django website using Nginx, Gunicorn, Postgres DB and apply SSL https://sleeksoft.in/deploy-django-website-in-ubuntu-server-using-nginx-gunicorn-and-wsgi-with-pos...

sudo systemctl status gunicorn.socket

Next, check for the existence of the gunicorn.sock �le within the /run directory

Copy
file /run/gunicorn.sock

Output : /run/gunicorn.sock: socket

If the systemctl status command show errors or if you do not �nd the gunicorn.sock �le in the directory, it’s an indication that the Gunicorn
socket was not able to be created correctly. Check the Gunicorn socket’s logs using the following command

Copy
sudo journalctl -u gunicorn.socket

Testing Socket Activation


Copy
Currently, we have started the gunicorn.socket unit, the gunicorn.service will not be active yet because the socket has not received any
connections. we can check this by using the following command

Copy
sudo systemctl status gunicorn

Output :

● gunicorn.service - gunicorn daemon


Loaded: loaded (/etc/systemd/system/gunicorn.service; disabled; vendor preset: enabled)
Active: inactive (dead)

To test the socket activation, we can send a connection to the socket through curl by using the following command

Copy
curl --unix-socket /run/gunicorn.sock localhost

You should see the HTML output from our django application in the terminal. This means that Gunicorn was started and was able to serve
our Django application. We can verify that the Gunicorn service is running by using the following command

Copy
sudo systemctl status gunicorn

Output :

gunicorn.service - gunicorn daemon


Loaded: loaded (/etc/systemd/system/gunicorn.service; disabled; vendor preset: enabled)
Active: active (running) since Mon 2021-05-10 21:00:35 UTC; 4s ago
Main PID: 1157 (gunicorn)
Tasks: 4 (limit: 1153)
CGroup: /system.slice/gunicorn.service
├─1157 /home/sleekproject/sleekenv/bin/python3 /home/sleekproject/sleekenv/bin/gunicorn --access-logfile -
├─1178 /home/sleekproject/sleekenv/bin/python3 /home/sleekproject/sleekenv/bin/gunicorn --access-logfile -
├─1180 /home/sleekproject/sleekenv/bin/python3 /home/sleekproject/sleekenv/bin/gunicorn --access-logfile -
└─1181 /home/sleekproject/sleekenv/bin/python3 /home/sleekproject/sleekenv/bin/gunicorn --access-logfile -
May 10 21:00:35 django1 systemd[1]: Started gunicorn daemon.
May 10 21:00:35 django1 gunicorn[1157]: [2018-07-09 20:00:40 +0000] [1157] [INFO] Starting gunicorn 19.9.0
May 10 21:00:35 django1 gunicorn[1157]: [2018-07-09 20:00:40 +0000] [1157] [INFO] Listening at: unix:/run/gunicorn.soc
May 10 21:00:35 django1 gunicorn[1157]: [2018-07-09 20:00:40 +0000] [1157] [INFO] Using worker: sync
May 10 21:00:35 django1 gunicorn[1157]: [2018-07-09 20:00:40 +0000] [1178] [INFO] Booting worker with pid: 1178
May 10 21:00:35 django1 gunicorn[1157]: [2018-07-09 20:00:40 +0000] [1180] [INFO] Booting worker with pid: 1180
May 10 21:00:35 django1 gunicorn[1157]: [2018-07-09 20:00:40 +0000] [1181] [INFO] Booting worker with pid: 1181
May 10 21:00:36 django1 gunicorn[1157]: - - [10/May/2021:21:00:36 +0000] "GET / HTTP/1.1" 200 16348 "-" "curl/7.58.0"

If the output from curl or the output of systemctl status indicates that a problem occurred, check the logs for additional details:

Copy
sudo journalctl -u gunicorn

Check the /etc/systemd/system/gunicorn.service �le for problems. If we make changes to the /etc/systemd/system/gunicorn.service �le,
reload the daemon to reread the service de�nition and restart the Gunicorn process using the following command

7 de 9 13/6/2022 13:45
Deploy Django website using Nginx, Gunicorn, Postgres DB and apply SSL https://sleeksoft.in/deploy-django-website-in-ubuntu-server-using-nginx-gunicorn-and-wsgi-with-pos...

sudo systemctl daemon-reload

Copy
sudo systemctl restart gunicorn

Section 6 : Configure Nginx web server


We need to con�gure Nginx to pass traf�c to the Gunicorn process. We need to create and open a new server block in Nginx’s sites-
available directory using the following command.

Copy
sudo touch /etc/nginx/sites-available/sleeksoft

Download this �le via FTP and start editing. We will add following in this server block.

• Specify that this block should listen on the normal port 80 and that it should respond to our server’s domain name or IP address.
• Instruct Nginx to ignore any problems with �nding a favicon.
• Instruct Nginx on where to �nd the static �les that we collected in our /sleekproject/static directory. All of these �les have a Copy
standard URI pre�x of “/static”, so we can create a location block to match those requests

Copy
server {
server_name example.com;

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


location /static/ {
alias /home/sleekproject/sleeksoft/static/;
}

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

Save, close and upload the �le via FTP when you are �nished. Now, we can enable the �le by linking it to the sites-enabled directory

Copy
sudo ln -s /etc/nginx/sites-available/sleeksoft /etc/nginx/sites-enabled

Test the Nginx con�guration for syntax errors by using the following command

Copy
sudo nginx -t

If no errors are reported, then we can go ahead and restart Nginx by using the following command

Copy
sudo systemctl restart nginx

Now, we need to open up our �rewall to normal traf�c on port 80. Since we no longer need access to the development server, we can
remove the rule to open port 8000 now.

Copy
sudo ufw delete allow 8000

Copy
sudo ufw allow 'Nginx Full'

We should now be able to go to our server’s domain or IP address to view our django application/website.

Section 7 : Certbot installtion for enabling SSL


Install snapd

Copy
sudo apt install snapd

Execute the following instructions on the command line on the machine to ensure that you have the latest version of snapd

8 de 9 13/6/2022 13:45
Deploy Django website using Nginx, Gunicorn, Postgres DB and apply SSL https://sleeksoft.in/deploy-django-website-in-ubuntu-server-using-nginx-gunicorn-and-wsgi-with-pos...

Copy
sudo snap install core; sudo snap refresh core

Run this command on the command line on the machine to install Certbot.

Copy
sudo snap install --classic certbot

Execute the following instruction on the command line on the machine to ensure that the certbot command can be run.

Copy
sudo ln -s /snap/bin/certbot /usr/bin/certbot

Run this command to get a certi�cate and have Certbot edit your Nginx con�guration automatically to serve it, turning on HTTPS access
in a single step.

Copy
sudo certbot --nginx

When prompted enter the desired value. This will automatically create SSL certi�cates for the pointed domain.

Now reboot the server.

Copy
reboot

Credits:

• Digital Ocean
• Barath Prabu S

SHARE THIS POST

  

Bharathi Nagar, Katpadi, Vellore.


+91 82486 40842, +91 99523 90868
[email protected]



© 2022 Sleeksoft. All Rights Reserved.

9 de 9 13/6/2022 13:45

You might also like