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.
Prerequisites:
To follow along with this guide, ensure the following are in place:
- 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).
- 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:
- Your project sits on /home/ubuntu/myblog
- Your project’s wsgi file sits /home/ubuntu/myblog/myblog
- 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
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
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
- A Practical Tutorial for Dockerizing Software Applications
- How to Configure a Docker App to a Domain Name
- Getting Started with Docker | Docker commands
- How To Run Scripts in Linux
- Deploy a Django Application on EC2 Instance with Nginx
- How to configure a domain to a docker container and install an SSL certificate on AWS