Django Deployment in Linux Vps
Django deployment
It is easy to get started with django and hard to go on a long run and deployment is even cumbersome.
Most of the time, for development, my personal favourite is Ubuntu, for deployment, Centos is my choice as it has been a defacto standard.
The WorkFlow I use for deployment.
Setting up a VPS.
-
spin up your vps with minimal centos installation with required libraries.
#!/usr/bin/env bash # Update the system sudo yum update # create a user that will deploy a django web applications. useradd webapps # Add a user to wheel group usermod -aG wheel webapps # Install epel repository sudo yum install epel-release # Install necessary libraries sudo "yum install Development Tools" -y # Install python related packages sudo yum install python3 python34-devel python-virtualenv python-pip # Install development tools sudo yum install vim git links # Install database packages yum install postgresql-devel postgresql-libs postgresql postgresql-server \ postgresql-contrib -y # Install database driver sudo yum install python-psycopg2 # Image related libraries sudo yum install libtiff-devel libjpeg-devel libzip-develfreetype-devel \ lcms2-devel libwebp-devel tcl-devel tk-devel -y # some DNS utilities yum install bind-utils
Prepare postgresql database
For most of my application, I use Postgresql, so, let’s install postgresql.
# Install database packages
yum install postgresql-devel postgresql-libs postgresql postgresql-server \
postgresql-contrib -y
# Install database driver
sudo yum install python-psycopg2After installing postgresql, let’s start postgresql server and enable postgresql for different run levels.
sudo systemctl enable postgresql
sudo systemctl start postgresqlAfter successful installation of postgresql, it’s time to prepare a database for our webapp.
postgresql create a user postgres as a super user during installation, we will use postgres user to create database for our webapp, a database user and a database user password.
# login using postgres user
sudo su - postgres
# create a database
createdb example_db
# create a user for example_db
createuser example_user --interactive
# login to psql shell
psql example_db
# set a password for example_user
ALTER USER example_user WITH PASSWORD 'yourpassword';
# grant all privileges for example user on example_db database
GRANT ALL ON DATABASE example_db to example_user;
# quit the database
\qNow it’s time to configure our webapp so that we can use a recently created database. Open your settings.py or any other database configuration file as per your web application architecture. Configure the following values as shown below.
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'example_db',
'USER': 'example_user',
'PASSWORD': 'yourpassword',
'HOST': '127.0.0.1',
'PORT': '5432',
}
}Ok, we are done with database server configuration. Now its time to install and setup Gunicorn.
Gunicorn install and setup.
Issue the following commands in your centos VPS to install gunicorn.
#.
(venv)# pip install gunicornAfter installing gunicorn, we will create a gunicorn_start.sh script to run the gunicorn server, which will ultimately controlled by supervisorctl.
On your project directory create a script called gunicorn_start.sh as shown below.
This script will used to launch gunicorn server.
#!/bin/bash
# Purpose: Gunicorn starter
# Author: manojit.gautam@gmail.com
# Name of an application
NAME="Your projectname"
# project directory
PROJECTDIR=/webapps/example.com
# django project virutalenv directory
VENVDIR=/webapps/example.com/venv
# Project source directory
SRCDIR=/webapps/example.com/master/src
# Sock file as gunicorn will communicate using unix socket
SOCKFILE=$PROJECTDIR/gunicorn.sock
# User who runs the app
USER=webapps
# the group to run as
GROUP=webapps
# how many worker processes should Gunicorn spawn
NUM_WORKERS=3
# which settings file should Django use
# If you haven't spit your file it should example.settings only
DJANGO_SETTINGS_MODULE=example.settings.production
# WSGI module name
DJANGO_WSGI_MODULE=example.wsgi
# Activate the virtual environment
source $VENVDIR/bin/activate
# Export the settings module
export DJANGO_SETTINGS_MODULE=$DJANGO_SETTINGS_MODULE
# Export the python path from virtualenv dir
export PYTHONPATH=$DJANGODIR:$PYTHONPATH
# move to src dir !IMPORTANT otherwise it won't work.
cd $SRCDIR
# Start your Django Unicorn
# Programs meant to be run under supervisor should not daemonize themselves (do not use --daemon)
exec $VENVDIR/bin/gunicorn ${DJANGO_WSGI_MODULE}:application \
--name $NAME \
--workers $NUM_WORKERS \
--user=$USER --group=$GROUP \
--bind=unix:$SOCKFILE \
--log-level=debug \
--log-file=-After configuring gunicorn_start.sh script, we need to install and configure supervisor to manage our webapp.
Install and Configure supervisor
Install supevisor.
# install Supervisor
sudo yum install Supervisor
# create the supervisor configuration script
# you need to create this script to work
echo_supervisord_conf > /etc/supervisord.conf
# create the site specific configuration and include in supervisord.conf file
# to include the below use include directives
[include]
files = /etc/supervisor/conf.d/*.confTo, manage and start gunicorn_start.sh web application starter script, we need to create a web application specific configuration file.
Create a configuration file example.com.conf inside /etc/supervisor/conf.d/ directory. as shown below.
touch /etc/supervisor/conf.d/example.com.confPaste the following contents in example.com.conf file.
[program:example]
command=/webapps/example.com/gunicorn_start.sh
user=webapps
stdout_logfile=/webapps/example.com/logs/gunicorn_supervisor.log
redirect_stderr=true
environment=LANG=en_US.UTF-8,LC_ALL=en_US.UTF-8 Install nginx
We will use Nginx as a webserver for our django web application.
Issue the following commands to install nginx.
sudo yum install nginx
sudo systemctl enable nginx
sudo systemctl start nginxCreate a web server configuration file for Django web app inside /etc/nginx/conf.d/ directory as example.conf
as shown below.
upstream example {
# fail_timeout=0 means we always retry an upstream even if it failed
# to return a good HTTP response (in case the Unicorn master nukes a
# single worker for timing out).
server unix:/webapps/example.com/gunicorn.sock fail_timeout=0;
}
server{
listen 80;
server_name example.com;
client_max_body_size 4G;
access_log /webapps/example.com/logs/nginx-access.log;
error_log /webapps/example.com/logs/nginx-error.log;
# Robot.txt configuration
# developers work on robot.txt more so it is suitable to push inside source code.
location /robots.txt {
alias /webapps/example.org/robots.txt;
}
# Static assets configuration
location /static/ {
alias /webapps/example.com/master/src/assets/;
expires 30d;
}
# Media configuration
location /media/ {
alias /webapps/example.com/master/src/media/;
expires 30d;
}
# Need to review
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
if (!-f $request_filename) {
proxy_pass http://example; #app name
break;
}
}
# Favicon configuration
location /favicon.ico {
alias /webapps/example.com/master/src/assets/img/favicon.ico;
}
# Prevent hidden files being serverd
location ~ /\. { access_log off; log_not_found off; deny all; }
# Error page configuration
error_page 500 502 503 504 /500.html;
location = /500.html {
root /webapps/example.com/master/src/static/;
}
}Now, restart the nginx server to load the configuration file for your django web application.
Start a web application using supervisorctl
supervisorctl start exampleTo stop the web application you can use supervisorctl as shown below.
supervisorctl stop examplePersonal blog of Manoj Gautam. I’m a Backend Developer who use Python, Django and JavaScript to develop software. I have created a website that contains free text and video tutorials on computer science subjects CodeSchoolNepal.
You may follow me on twitter or join my Linkedin for latest updates.