You are currently viewing Deploy a Django Application on EC2 Instance with Nginx

Deploy a Django Application on EC2 Instance with Nginx

If you’re looking to take your Django web application live and make it accessible to the world, deploying it on an Amazon Elastic Compute Cloud (EC2) instance is both a cost-effective and scalable solution. In this article, we’ll walk you through the steps to deploy a Django application on an EC2 instance and set up the Nginx web server to serve your application to users.

Deploy a Django Application on EC2 Instance with Nginx

Prerequisites:

To follow along with this guide, ensure the following are in place:

  1. An AWS EC2 Instance: Launch an EC2 instance using the AWS Management Console. Select your desired operating system, in this illustration, we use Ubuntu OS, and configure your security groups to allow incoming traffic on ports 80 and 22 (HTTP and SSH).
  2. Django Application: You should have your Django web application ready for deployment. Ensure it’s working correctly on your local development machine. It’s recommended that you push the project on GitHub.

Step 1: SSH into Your EC2 Instance

If you have generated a private key for your EC2 instance, use the method below to access your instance. Replace /path/to/your/key.pem with the path and the name of your private key file. By default, ubuntu user has access to the instance unless otherwise set. Set your_ec2_ip to the IP for your instance or the public DNS. Fetch this information from the instance dashboard.

ssh -i /path/to/your/key.pem ubuntu@your_ec2_ip

If you did not set up the private key, you can access the instance directly from the instance dashboard. Once logged in, proceed.

Step 2: Update Your System

Run the following commands to update the system.

sudo apt update
sudo apt upgrade

Step 3: Install Required Software

Install the required software: python3-pip, python3-venv, nginx, and supervisor. Once installed, start nginx service if not started.

sudo apt install python3-pip python3-venv nginx supervisor
sudo service nginx start

Step 4: Set Up a Virtual Environment

It’s recommended that you set up a virtual environment for the installation of your project’s dependencies. In this case, the assumption is that you are in the location /home/ubuntu.

python3 -m venv env
source env/bin/activate

Step 5: Clone/Upload Website files

If you have the project ready on Github, clone it under the same location: /home/ubuntu. Alternatively, use the SCP method to upload the data and extract it under the same location.

git clone https://github.com/danielnjama/complete-blog.git
#where https://github.com/danielnjama/complete-blog.git is the link to your repository
scp -i key.pem file.zip username@your_ec2_ip:/home/ubuntu
#key.pem is your private key. File.zip is the compresed files of your project. 

To ensure you don’t miss the steps; the project uploaded for this project is under the root folder myblog.

Step 6: Install gunicorn and other dependencies

Run the dependancy installation command; with the assumption that you have the dependancies defined in a requirements.txt file.

pip install -r requirements.txt
pip install gunicorn

Step 7: Configure gunicorn

Navigate to the supervisor folder, create file gunicorn.conf and add the gunicorn code as below:

cd /etc/supervisor/conf.d/
sudo touch gunicorn.conf 
sudo nano gunicorn.conf
#then add the following
[program:gunicorn]
directory=/home/ubuntu/myblog
command=/home/ubuntu/env/bin/gunicorn --workers 3 --bind unix:/home/ubuntu/myblog/app.sock myblog.wsgi:application  
autostart=true
autorestart=true
stderr_logfile=/var/log/gunicorn/gunicorn.err.log
stdout_logfile=/var/log/gunicorn/gunicorn.out.log

[group:guni]
programs:gunicorn

The assumptions made:

  1. Your project sits on /home/ubuntu/myblog
  2. Your project’s wsgi file sits /home/ubuntu/myblog/myblog
  3. Your virtualenv is named env and sits in the path: /home/ubuntu/env

Adjust the paths as needed to match your exact paths.

Step 8: Create the folders that will hold the error log files

Run the following command to create the error log folders as defined in the code above:

sudo mkdir /var/log/gunicorn

Step 9: Update the Supervisor service

To connect the nginx service with the supervisor, run the following:

sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl status
supervisor status: deploy a Django application on EC2 instance

The status should show that the service is up and running. In case the service is not up and running, check the logs:

cat /var/log/gunicorn/gunicorn.err.log
#If errors indicated are resolved, restart the supervisor service and check the status again
sudo supervisorctl restart all
sudo supervisorctl status

Step 10: Update the user defined in the nginx.conf file

To prevent permissions-related issues, navigate to the nginx configurations and update the nginx.conf file from the www-date user to root

sudo vi /etc/nginx/nginx.conf
#edit the line with >> user www-data;  to >> user root;

Step 11: Create a django.conf file to connect the nginx web server and the Django project

cd /etc/nginx/sites-available/
sudo vi django.conf

Add the following code:

server{

	listen 80;
	server_name serverIP;  #replace serverIp with the correct IP or domain www.domain

	location /static/ {
        root /home/ubuntu/myblog;
    }

	location / {

		include proxy_params;
		proxy_pass http://unix:/home/ubuntu/myblog/app.sock;

	}

}

Once the above update is done, test the nginx configuration.

sudo nginx -t    #If it returns Ok/success message, everything is working as needed.

Step 12: Enable Nginx Configuration

Create a symbolic link to your Nginx configuration in the sites-enabled directory:

sudo ln django.conf /etc/nginx/sites-enabled
sudo service nginx restart

At this stage, the website should be reachable. If you set up the server name as the IP, access your website using the IP; if you used both the IP and the domain, it should be accessible on the domain name as well: ensure to link your DNS records for your domain name with the server IP. See a video on how to point the DNS for your domain name to your Instance IP on cloudlare

How to Add a domain and Manage DNS records on Cloudflare

Should the website show errors related to some settings, eg in the settings.py file, rectify and remember to restart the supervisor and the nginx services:

sudo service supervisor restart
sudo service nginx restart

How to redirect Server IP to domain name

If you configure a domain name to serve your website, you may want to redirect a user who accesses the server IP to the domain name instead. This is achieved by creating 2 server blocks in the sites-available configuration file. See below:

sudo vi /etc/nginx/sites-available/django.conf  #open the django.conf to edit

Add Redirection Configuration:

Add a server block that listens on port 80 and redirects all requests to your domain. This block should come before the server block that serves your Django application.

server {
    listen 80;
    server_name your_ec2_ip;

    return 301 http://dtechnologys.com$request_uri;
}

Modify Django Application Configuration:

Add or update the server block that serves your Django application to use the server_name directive for your domain: in this case, we have set our domain name to dtechnologys.com. Replace this with your domain name.

server{

	listen 80;
	server_name dtechnologys.com www.dtechnologys.com; 

	location /static/ {
        root /home/ubuntu/myblog;
    }

	location / {

		include proxy_params;
		proxy_pass http://unix:/home/ubuntu/myblog/app.sock;

	}

}

Make a donation to support us



Web Hosting and email hosting Packages


For web development services, SEO services, Digital marketing strategies, website set up services, web hosting and domain registration; contact Dynamic Technologies.