Deploy Django Project on Ubuntu 16.04 Production Server step by step

Mohammad Raisul islam
4 min readSep 1, 2020

Django is a high-level Python Web framework that encourages rapid development and clean, pragmatic design. It provides the developers a dedicated development server which is also known as testing server as well.Django in production is to run with Gunicorn and use Nginx as a reverse proxy so it gives more security to our application.In this post I will explain how one can run the Django application in the Production environment. So Let’s get started.

SSH & update ubuntu instance:

chmod 400 path-to-your-key.pem (for read permission)

ssh -i path-to-your-key.pem ubuntu@your-aws-instance-public-ip (We need to ssh into our EC2 instance)

sudo apt-get update && sudo apt-get upgrade -y

Setting up our project

We’ll be setting up our project in the default directory of nginx (/var/www/html). Here we can easily clone our project from service like github, bitbucket etc. For that we have to provide some permissions to our user.

sudo usermod -a -G www-data <username default is ubuntu>

sudo chown -R <username default is ubuntu>:www-data /var/www

sudo chmod 2775 /var/www

find /var/www -type d -exec sudo chmod 2775 {} +

find /var/www -type f -exec sudo chmod 0664 {} +

As we have cloned the git repo into var/www/html so this is our BASE_DIR for our django project. Right now we will be installing our required python packages into virtual environment.

sudo apt install python3-pip

sudo pip3 install virtualenv

virtualenv -p python3 venv # install it inside /var/www/html

sudo apt-get install python-dev python3-devActivate virtualenv from within /var/www/html using the command.

source venv/bin/activate

Then we will install the requirements for our project, and install gunicorn which is the key to running our application as a service within the server spontaneously.

Configuring Gunicorn

In production we won’t be using Django’s single-threaded development server, but a dedicated application server called Gunicorn.

  • Install gunicorn in your application’s virtual environment

pip install gunicorn

  • Test Sample Application with Gunicorn Server

Now that you have gunicorn, you can test whether it can serve your Django application by running the following command:

gunicorn website.wsgi:application — bind 0.0.0.0:8000

To configure gunicorn as a service, we will need to write a .service file within ubuntu’s system.

sudo nano /etc/systemd/system/gunicorn.service

Here, we will write a .service script to run gunicorn and create a .sock file within our project root directory. This .sock file will be accessed by Nginx to serve our application to the internet. A demo .service file:

File name: gunicorn.service -> This is also the name through which the gunicorn will be enabled as a service.

[Unit]

Description=gunicorn daemon

After=network.target

[Service]

User=ubuntu

Group=www-data

WorkingDirectory=/var/www/html

ExecStart=/var/www/html/gunicorn_start.sh

[Install]

WantedBy=multi-user.target

Now we have to edit the gunicorn_start.sh file under the directory /var/www/html/.

NAME=”website” #Name of the application (*)

DJANGODIR=/var/www/html/website/ # Django project directory (*)

SOCKFILE=/var/www/html/website/website.sock # we will communicate using this unix socket (*)

USER=ubuntu # the user to run as (*)

GROUP=www-data # the group to run as (*)

NUM_WORKERS=3 # how many worker processes should Gunicorn spawn (*)

DJANGO_SETTINGS_MODULE=website.settings # which settings file should Django use (*)

DJANGO_WSGI_MODULE=website.wsgi # WSGI module name (*)

# Activate the virtual environment

cd $DJANGODIR

source /var/www/html/venv/bin/activate

export DJANGO_SETTINGS_MODULE=$DJANGO_SETTINGS_MODULE

export PYTHONPATH=$DJANGODIR:$PYTHONPATH

# Create the run directory if it doesn’t exist

RUNDIR=$(dirname $SOCKFILE)

test -d $RUNDIR || mkdir -p $RUNDIR

# Start your Django Unicorn

# Programs meant to be run under supervisor should not daemonize themselves (do not use — daemon)

exec /var/www/html/website/venv/bin/gunicorn ${DJANGO_WSGI_MODULE}:application \

— name $NAME \

— workers $NUM_WORKERS \

— user $USER \

— bind=unix:$SOCKFILE

After this, we need to enable and start gunicorn as a service using the following commands.

sudo systemctl enable gunicorn.service

sudo systemctl start gunicorn.service

Installing Nginx

Time to set up Nginx as a server for our application and its static files.

  • Install and start Nginx

sudo apt-get install nginx

sudo service nginx start

Each Nginx virtual server should be described by a file in the /etc/nginx/sites-available directory. You select which sites you want to enable by making symbolic links to those in the /etc/nginx/sites-enabled directory.

Now, to check if nginx was installed properly, we would need to configure nginx so that our server is connected to the internet. For a basic setup, we can follow the basic steps.

sudo nano /etc/nginx/sites-available/default

In the configuration file, there is a parameter within server, server_name. We need to put the IP address of our cloud server there, and easily check if the server is connected or not!

server {

listen 80;

server_name <server_ip>;

}

After this, run the following command.

sudo ln -s /etc/nginx/sites-available/default /etc/nginx/sites-enabled

Then we will restart our nginx server.

sudo systemctl restart nginx

As we said before, nginx will be reverse proxying the gunicorn application server through the .sock file in the project root. This can be done by setting the location parameter within the nginx script. A basic demo nginx configuration:

server {

listen 80;

server_name <server_ip>;

location /static/ {

autoindex on;

alias /var/www/html/static/;

expires 1M;

access_log off;

add_header Cache-Control “public”;

proxy_ignore_headers “Set-Cookie”;

}

location / {

include proxy_params;

Proxy_pass http://unix:/var/www/html/<project_root>/<project_root_socket_gunicorn>.sock;

}

}

Now your nginx is ready to serve requests and it will forward it to your application but for this make sure you have a gunicorn server running.

Go to your browser and type <ec2-instance-dns> this will send a request to nginx and then it will forward that request to your server running with gunicorn.

Now, after we restart gunicorn and nginx, and provided that we have set up our project appropriately (setting up environment variables, adding the server IP address in ALLOWED_HOST etc.) we will be able to visit our django powered website using our server IP address!

Troubleshooting Nginx

The primary place to look for more information is in Nginx’s error logs. Generally, this will tell you what conditions caused problems during the proxying event. Follow the Nginx error logs by typing:

sudo tail -F /var/log/nginx/error.log

Personally, difficulties i faced during deployment was roots most of the times. So write the roots perfectly during deployment.
(inspired by

vai)

--

--