How to deploy a Django application to the Ubuntu 18.0.4 LTS AWS EC2 instance.

Eyakub Sorkar
3 min readJan 28, 2020

While deploying a Django application on AWS EC2 instance, we might get confused because there are a few ways to do it. So I thought I would write up something step by step.

Let’s start

Prerequisites:

  1. Running Ubuntu 18.0.4 LTS EC2 instance on your AWS.
  2. On your Security group open 22, 80 port.
  3. The project you want to deploy on your Git.

Setting up Python environment:

sudo apt-get update -y && apt-get upgrade -y
sudo apt-get install python3-pip
sudo python3 -m pip install virtualenv

Setting up your Django project:

https://github.com/username/your-repo.git
cd your-repo
virtualenv venv
source venv/bin/activate
pip install -r requirements.txt
pip install gunicorn

Here, after cloning the repository, go inside the repo and create your virtual environment for your project and activate it. Don’t forget to install packages from your requirements.txt, besides install gunicorn too.

Setting up Application server:

sudo apt-get install nginx

NGINX is open-source software for web serving, reverse proxying, caching, load balancing, media streaming, and more. It started out as a web server designed for maximum performance and stability.

sudo nano /etc/systemd/system/app-name.service
[Unit]
Description=gunicorn daemon
Requires=app-name.socket
After=network.target
[Service]
User=ubuntu
Group=www-data
WorkingDirectory=/home/ubuntu/your-repo
ExecStart=/home/ubuntu/your-repo/venv/bin/gunicorn \
--access-logfile - \
--workers 3 \
--bind unix:/home/ubuntu/your-repo/app.sock \
your-repo.wsgi:application
[Install]
WantedBy=multi-user.target

Now, a socket file

sudo nano /etc/systemd/system/app-name.socket[Unit]
Description=gunicorn socket
[Socket]
ListenStream=/home/ubuntu/your-repo/app.sock
[Install]
WantedBy=sockets.target

run -> sudo systemctl enable app-name.socket

Create both service and socket file, as that’s for setting up like gunicorn. Since you are deploying Django, which is a web framework, you need something bridging the talk between the web server (Nginx) and the web framework (Django). In Python world, such a thing is called a WSGI application server (but think it like a middle ware), examples of which include Gunicorn and uWSGI. When handling a request, Nginx proxies the request to Gunicorn or uWSGI, which in turn calls Django code and returns the response.

Now your Nginx conf file

sudo nano /etc/nginx/sites-available/your-repo.confserver {
listen 80;
server_name server_ip subdomain.domain.com;
location = /favicon.ico { access_log off; log_not_found off; } location /static/ {
root /home/ubuntu/your-repo;
}
location / {
include proxy_params;
proxy_pass http://unix:/home/ubuntu/your-repo/app.sock;
}
}

Static: this is to locate the static file destination

/: this is the root and indicating the sock file

sudo ln -s /etc/nginx/sites-available/nginx-app.conf /etc/nginx/sites-enabled/nginx-app.conf

Now all you have to do is

sudo systemctl daemon-reload
sudo systemctl start app-name
sudo systemctl enable app-name
sudo service nginx restart

Domain & subdomain setup:

Set up an “A Record” with “Host” set to @ and “Value” set to {{IP ADDRESS}}

Set up “CNAME Record” with “Host” set to {{SUBDOMAIN}} and Value set to {{DOMAIN NAME}}

Final step:

Oh, you wanna do more steps? hope this will work, you don’t have to worry about other things. You are good to go. Try your domain now.

--

--

Eyakub Sorkar

Full-Stack Software Engineer. Currently working on Django, besides trying to go through React, Docker, AWS.