Deploy Django with NginX, Gunicorn, PostgreSQL, virtualenv

Step 0 – Update and upgrade

We are using Ubuntu 16.04 LTS for this tutorial
ubuntu version
apt-get update update the list of available packages and their versions, but it does not install or upgrade any packages. apt-get upgrade actually installs newer versions of the packages you have. After updating the lists, the package manager knows about available updates for the software you have installed.
$ sudo apt-get update
$ sudo apt-get upgrade

Enable SSH (optional)

In case of Ubuntu 16.04 server, ssh isn’t enabled.
$ sudo apt-get purge openssh-server
$ sudo apt-get install openssh-server


Step 1 – Install the dev packages

The *-dev packages contain the C header files (statically compiled versions i.e. *.so files).
$ sudo apt-get install build-essential libpq-dev libssl-dev openssl libffi-dev zlib1g-dev

Step 2 – Install Python 3.6 (optional)

By default Ubuntu 16.04 LTS has Python 3.5.2 installed. It’s a good practice to start with the latest stable version – Python 3.6.x. Problem is Python 3.6 is not available for direct install, via the default repositories, but as third party PPA. Here’s a step-by-step guide for installing Python 3.6 on Ubuntu.

Install Python dev and pip

$ sudo apt-get install vim python3-pip python3-dev software-properties-common python-software-properties

Add Python 3.6 repository

$ sudo add-apt-repository ppa:jonathonf/python-3.6

Update and install

$ sudo apt-get update
$ sudo apt-get install python3.6
Python 3.6

Create virtual environment

$ sudo pip3 install virtualenv
$ virtualenv -p /usr/bin/python3.6 ~/virtualenvs/venv_devopspy
$ source virtualenvs/venv_devopspy/bin/activate
(venv_devopspy) nahmed@ubuntu:~$
django venv

Step 3 – Install  and configure Postgresql

Here’s a step-by-step guide for installing PostgreSQL on Ubuntu.

Add Postgresql repository

$ sudo add-apt-repository "deb http://apt.postgresql.org/pub/repos/apt/ $(lsb_release -sc)-pgdg main"
$ wget -q -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -

Install Postgresql 9.6

$ sudo apt-get update
$ sudo apt-get install postgresql-9.6 postgresql-contrib
start postgres

Create user and database

The Posgresql installation itself creates the postgres user, and psql is the command-line utility for PostgreSQL.
$ sudo -u postgres psql postgres
postgres=# create user devopspy_user with password  'devopspy!';
postgres=# create database devopspy_db;
postgres=# grant all privileges on database devopspy_db to devopspy_user;
postgres=# \q

Verify

$ psql -h localhost devopspy_db -U devopspy_user -W
psql


Step 4 – Clone or create Django project

If you already have your Django project ready, or have it as a Git repository, the following steps are not for for you.
Make sure you have the virtual environment activated (created above).

Install Django

$ pip install django==1.11

Start project

$ mkdir /var/www/
$ sudo chown -R nahmed:nahmed /var/www/
$ cd /var/www/
$ django-admin startproject devops_project

Install requirements

$ cd devops_project
$ pip install psycopg2

Create requirements.txt (optional)

$ pip freeze > requirements.txt

Add DB settings

You can find the settings.py in the project folder i.e. inside /var/www/devops_project/devops_project. Open settings.py using editor of your choice
vim settings.py
Update the DATABASES dictionary as follows:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'devopspy_db',
'USER': 'devopspy_user',
'PASSWORD': 'devopspy!',
'HOST': 'localhost',
'PORT': 5432,
}
}

update ALLOWED_HOST

ALLOWED_HOSTS = ['*']

Make migrations

You can find the manage.py at project root
$ python3.6 manage.py migrate
 django migrate

Verify (optional)

This step is to verify if our Django project is Ok. You must shutdown the server using ctrl+c. As gunicorn will be using the same port i.e. 8000
python3.6 manage.py runserver
django runserver


Step 5 – Install and configure Gunicorn

$ pip install gunicorn
To start gunicorn, it’ll be the Django app server, for which NginX will be acting as a reverse proxy.

Option 1 – Start the app server

Execute the following at project root – it is not recommend for production setups, you must register gunicorn as systemd service (option 2, below)
$ gunicorn -b 0.0.0.0:8000 devops_project.wsgi

Option 2 – Register Gunicorn systemd service

Create a service file

$ sudo vim /etc/systemd/system/gunicorn.service

Copy paste the following into the gunicorn.service file

[Unit]
Description=gunicorn daemon
After=network.target[Service]
User=nahmed
Group=www-data
WorkingDirectory=/var/www/devops_project
ExecStart=/home/nahmed/virtualenvs/venv_devopspy/bin/gunicorn --access-logfile - --workers 3 --bind unix:/var/www/devops_project.sock devops_project.wsgi

[Install]
WantedBy=multi-user.target
systemd unit

Start the gunicorn service

$ sudo systemctl status gunicorn
$ sudo systemctl daemon-reload
$ sudo systemctl restart gunicorn
$ sudo systemctl enable gunicorn.service

Step 6 – Install and configure NginX

Install NginX

$ sudo apt-get install nginx

Create project conf

$ sudo vim /etc/nginx/sites-available/devops_project
Add the following to the devops_project conf file
server {
listen 80;
server_name 0.0.0.0;location / {
include proxy_params;
proxy_pass http://unix:/var/www/devops_project.sock;

}
}

Delete default conf (optional)

As it has a default content set to be served on port 80. In case you want to listen at some port other than 80, no need to delete the default.
$ sudo rm -rf /etc/nginx/sites-enabled/default

Enable project conf

$ sudo ln -s /etc/nginx/sites-available/devops_project /etc/nginx/sites-enabled

Verify NginX conf

NginX configuration can be validated for any errors before restarting NginX, and putting it in down state.
sudo nginx -t
Output
nahmed@ubuntu:/etc/nginx/sites-available$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Restart and enable NginX

$ sudo systemctl restart nginx
$ sudo systemctl enable nginx

Verification

django dashboard

Leave a Reply

Your email address will not be published. Required fields are marked *