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 updatesudo apt install python3-pip python3-dev nginxThis will install python, pip, and Nginx server
Step 5: Creating a Python virtual environment
sudo pip3 install virtualenv
sudo apt install python3-virtualenvThis 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 ~/blogprojectdrfthen
virtualenv envA virtual environment named env will be created. Let’s activate this virtual environment:
source env/bin/activatepip install -r requirements.txt
Step 6: Installing Django and gunicorn
pip install django gunicornThis 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 makemigrationspython manage.py migratepython manage.py collectstatic
Import Thing about static files, You must make sure to add few lines in your seeting.py file.
- Add this line, “whitenoise.runserver_nostatic”, into your Installed_apps of setting file.
- Add ‘whitenoise.middleware.WhiteNoiseMiddleware’, into MiddleWare of your setting File.
- 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 #new5. Run this command
$ pip install whitenoise
Step 8: Configuring gunicorn
Deactivate the virtual environment by executing the command below:
deactivateLet’s create a system socket file for gunicorn now:
sudo vim /etc/systemd/system/gunicorn.socketPaste the contents below and save the file
[Unit]
Description=gunicorn socket[Socket]
ListenStream=/run/gunicorn.sock[Install]
WantedBy=sockets.targetNext, we will create a service file for gunicorn
sudo vim /etc/systemd/system/gunicorn.servicePaste 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.targetLets 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/blogPaste 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 nginxsudo 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/tcpsudo 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!