Skip to main content

How to host Django Application in AWS using gunicorn & nginx in Production

in this post, we will see how to use  nginx with  gunicorn to serve  django  applications in production. 


Django is a very powerful web framework and ships with a server which is able to facilitate development. This development server is not scalable and is not suited for production. Hence we need to configure gunicorn to get better scalability and nginx can be used as a reverse proxy and as a web server to serve static files. Let's get started 

Step 1 - Installing python and nginx

Let's update the server's package index using the command below:

sudo apt update
sudo apt install python3-pip python3-dev nginx

This will install python, pip and nginx server

Step 2 - Creating a python virtual environment 

sudo pip3 install virtualenv

This will install a virtual environment package in python. Let's create a project directory to host our Django application and create a virtual environment inside that directory.

mkdir ~/projectdir
cd ~/projectdir
virtualenv env

A virtual environment named env will be created. Let's activate this virtual environment:

source env/bin/activate

Step 3 - Installing Django and gunicorn

pip install django gunicorn

This installs Django and gunicorn in our virtual environment

Step 4 - Setting up our Django project

At this point you can either copy your existing  Django project into the projectdir folder or create a fresh one as shown below:

django-admin startproject textutils ~/projectdir

Add your IP address or domain to the ALLOWED_HOSTS variable in settings.py.

If you have any migrations to run, perform that action:

~/projectdir/manage.py makemigrations
~/projectdir/manage.py migrate

Let's test this sample project by running the following commands:

sudo ufw allow 8000

This opens port 8000 by allowing it over the firewall. Let's start our  Django development server to test the setup so far:

~/projectdir/manage.py runserver 0.0.0.0:8000

Step 5 - Configuring gunicorn

Lets test  gunicorn's ability to serve our  application by firing the following commands:

gunicorn --bind 0.0.0.0:8000 textutils.wsgi

This should start gunicorn on port 8000. We can go back to the browser to test our application. Visiting http://<ip-address>:8000 shows a page like this:

Deactivate the virtualenvironment by executing the command below:

deactivate

Let's create a system socket file for gunicorn now:

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

Paste the contents below and save the file

[Unit]
Description=gunicorn socket

[Socket]
ListenStream=/run/gunicorn.sock

[Install]
WantedBy=sockets.target

Next, we will create a service file for gunicorn

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

Paste the contents below inside this file:

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

[Service]
User=harry
Group=www-data
WorkingDirectory=/home/harry/projectdir
ExecStart=/home/harry/projectdir/env/bin/gunicorn \
          --access-logfile - \
          --workers 3 \
          --bind unix:/run/gunicorn.sock \
          textutils.wsgi:application

[Install]
WantedBy=multi-user.target

Lets now start and enable the gunicorn socket

sudo systemctl start gunicorn.socket
sudo systemctl enable gunicorn.socket

Step 6 - Configuring Nginx as a reverse proxy

Create a configuration file for Nginx using the following command

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

Paste the below contents inside the file created

server {
    listen 80;
    server_name www.codewithharry.in;

    location = /favicon.ico { access_log off; log_not_found off; }
    location /static/ {
        root /home/harry/projectdir;
    }

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

Activate the configuration using the following command:

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

Restart  nginx and allow the changes to take place.

sudo systemctl restart nginx

Your Django website should now work fine! Happy Coding

Comments

Popular posts from this blog

Connect and Configure MongoDB in Django Project

  Django, a high-level Python web framework, is well-known for its robustness and versatility. While Django natively supports popular databases like PostgreSQL and MySQL, you may want to integrate a NoSQL database like MongoDB for specific use cases. MongoDB’s flexibility and scalability make it an excellent choice for handling unstructured data. In this blog, we will walk you through the process of connecting MongoDB to a Django project, enabling you to harness the power of NoSQL in your web applications. Prerequisites: Before we begin, ensure you have the following prerequisites in place: Django installed on your system. MongoDB database server installed and running. Basic familiarity with Django project structure and database concepts. Virtual Environment, this is optional but recommended. You check our blog  here . Note:  For this tutorial, we are using our basic  skeleton project  for Django. You can also download the project from  here . Step 1: Insta...

Mongodb-CheatSheet

  All MongoDb commands you will ever need (MongoDb Cheatsheet) In this post, we will see a comprehensive list of all the    MongoDB  commands you will ever need as a MongoDB beginner. This list covers almost all the most used commands in MongoDB. I will assume that you are working inside a collection named 'comments' on a MongoDB    database  of your choice 1. Database Commands View all databases show dbs Copy Create a new or switch databases  use dbName Copy View current Database db Copy Delete Database  db . dropDatabase ( ) Copy 2. Collection Commands Show Collections show collections Copy Create a collection named 'comments' db . createCollection ( 'comments' ) Copy Drop a collection named 'comments' db . comments . drop ( ) Copy 3. Row(Document) Commands Show all Rows in a Collection  db . comments . find ( ) Copy Show all Rows in a Collection (Prettified) db . comments . find ( ) . pretty ( ) Copy Find the first row matching the ob...