Back to Blog
Oct 7, 20226 min read

Deploy Django Application using gunicorn & Nginx in Production on AWS Ubuntu server

AWSDjangoPythonLinuxNginx
Deploy Django Application using gunicorn & Nginx in Production on AWS Ubuntu server

Django is a popular web framework for building web applications in Python. It is fast, secure, and scalable, making it a great choice for businesses of all sizes. If you are looking to deploy your Django application on the cloud, Amazon Web Services (AWS) is a great option. AWS offers a range of services that can help you deploy and manage your application with ease.

In this article, we will walk you through the steps to deploy a Django application on AWS using the EC2 (Elastic Compute Cloud) service using Nginx with gunicorn.

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 a web server to serve static files. Let’s get started

You can also watch the Video tutorial as well.

Step 1: Create an EC2 Instance

The first step in deploying a Django application on AWS is to create an EC2 instance. An EC2 instance is a virtual server that runs in the AWS cloud. To create an EC2 instance, you will need to log in to your AWS account and go to the EC2 dashboard.

Once you are in the EC2 dashboard, click on the “Launch Instance” button. From there, you will be prompted to select an Amazon Machine Image (AMI). An AMI is a pre-configured virtual machine image that includes the operating system, application server, and other software needed to run your application.

For this tutorial, we will use the Amazon Ubuntu Machine. After selecting the AMI, select the instance type that best suits your needs. For small to medium-sized applications, a t2.micro instance is a good choice.

Step 2: Configure Security Group

After creating the EC2 instance, you must configure the security group. The security group controls the incoming and outgoing traffic to and from your EC2 instance. To configure the security group, go to the “Security Groups” section of the EC2 dashboard and create a new security group.

Add the following rules to the security group to allow incoming traffic:

  • SSH (port 22) for remote access to your instance
  • HTTP (port 80) for web traffic
  • HTTPS (port 443) for secure web traffic

Step 3: Connect to your EC2 Instance

Now that you have created and configured your EC2 instance, it’s time to connect to it. You will need to use an SSH client to connect to your instance. If you are using a Mac or Linux machine, you can use the terminal. If you are using Windows, you can use PuTTY.

Step 4: 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 5: Creating a Python virtual environment

sudo pip3 install virtualenv
sudo apt install python3-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.

git clone https://github.com/rashiddaha/blogprojectdrf.git
cd ~/blogprojectdrf
then
virtualenv env

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

source env/bin/activate
pip install -r requirements.txt

Step 6: Installing Django and gunicorn

pip install django gunicorn

This installs Django and gunicorn in our virtual environment

Step 7: Setting up our Django project

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

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

python manage.py makemigrations
python manage.py migrate
python manage.py collectstatic

Import Thing about static files, You must make sure to add few lines in your seeting.py file.

  1. Add this line, “whitenoise.runserver_nostatic”, into your Installed_apps of setting file.
  2. Add ‘whitenoise.middleware.WhiteNoiseMiddleware’, into MiddleWare of your setting File.
  3. Also, add these lines at the bottom of the blog/urls. py file.
if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root = settings.MEDIA_ROOT)
    urlpatterns += static(settings.STATIC_URL, document_root = settings.STATIC_URL)

4. Also, add these imports lines at the top of the blog/urls. py file.

from django.conf import settings # new
from  django.conf.urls.static import static #new

5. Run this command

$ pip install whitenoise

Step 8: Configuring gunicorn

Deactivate the virtual environment by executing the command below:

deactivate

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

sudo vim /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 vim /etc/systemd/system/gunicorn.service

Paste the contents below inside this file:

[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target
[Service]
User=ubuntu
Group=www-data
WorkingDirectory=/home/ubuntu/blogprojectdrf
ExecStart=/home/ubuntu/blogprojectdrf/env/bin/gunicorn \
          --access-logfile - \
          --workers 3 \
          --bind unix:/run/gunicorn.sock \
          blog.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 

with this command, you can check if already a file exists.

cd /etc/nginx/sites-enabled/

Step 9: Configuring Nginx as a reverse proxy

Create a configuration file for Nginx using the following command

sudo vim /etc/nginx/sites-available/blog

Paste the below contents inside the file created

server {
    listen 80 default_server;
    server_name _;
    location = /favicon.ico { access_log off; log_not_found off; }
    location /static/ {
        root /home/ubuntu/blogprojectdrf;
    }
    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/blog /etc/nginx/sites-enabled/

Run this command to load a static file

$ sudo gpasswd -a www-data username

Restart nginx and allow the changes to take place.

sudo systemctl restart nginx
sudo service gunicorn restart
sudo service nginx restart

Additionally in case of errors

To check error logs

$ sudo tail -f /var/log/nginx/error.log

to check nginx working fine

$ sudo systemctl status nginx

sudo fuser -k 8000/tcp
sudo lsof -t -i tcp:8000 | xargs kill -9. # to kill termianl
# https://amalgjose.com/2020/02/27/gunicorn-connection-in-use-0-0-0-0-8000/

Cheers!

If you enjoyed my article, show your appreciation with a round of applause! 👏 Your support means the world to me!

Feel free to connect with me across various social media channels! Join me on LinkedIn, YouTube, Twitter, GitHub, and Upwork. Your support means a lot. Thanks for taking the time to read this!

💬 Got questions? Ask me anything!