Deploy Django app on AWS

Deploy and host a django application on AWS EC2 instance using Nginx as the webserver and Gunicorn as WSGI

Nginx is an open-source web server that, since its success as a web server, is now also used as a reverse proxy , HTTP cache, and load balancer.

WSGI used to forward request from a web server to a python backend.

Please Refer: HTTP request-response lifecycle

1. Initial setup

Create EC2 instance

Create/Launch EC2 instance: /tags/ec2/

Connect to EC2 instance

# Connect
ssh -i "name.pem" ubuntu@host

Install the latest patch of python 3.6

Python and PIP installation: /tags/python-setup/

Update and install python-pip and virtualenv

sudo apt-get update
sudo apt-get -y upgrade
sudo apt install python3-pip

2. Install git and configure user and email and clone repo

# Install
sudo apt-get install git-core

# Configure
git config --global user.name "Amrit"
git config --global user.email "[email protected]"

# Clone Repo
git clone -b aws-django https://github.com/amrit94/deployment-demo.git

3. Make virtual-env and install requirements.txt

# Install
pip install virtualenv
sudo apt install python3.8-venv

# Make Venv
mkdir ~/.virtualenvs/
cd ~/.virtualenvs/
python3.6 -m venv testvenv

# Activate venv
source ~/.virtualenvs/testvenv/bin/activate

# Install all requirements.txt
cd ~/deployment-demo/
pip install -r requirements.txt

Issue

# psycopg2 --> installation issue
pip install psycopg2-binary

sudo apt install libpq-dev

# Python.h issue
sudo apt install libpython3.6-dev

4. Setup Database

Install Postgresql and configure new role and grant all permissions

sudo apt-get install postgresql
sudo /etc/init.d/postgresql start
sudo -u postgres psql

postgres=# CREATE DATABASE testdb;
postgres=# CREATE ROLE testuser WITH LOGIN PASSWORD 'password';
postgres=# GRANT ALL PRIVILEGES ON DATABASE testdb TO testuser;

OR Install Mysql and add new user with all the privileges

sudo apt-get update
sudo apt-get install mysql-server   (Remember the password entered for root user)
mysql_secure_installation
mysql -u root -p

mysql> CREATE DATABASE testdb;
mysql> CREATE USER 'testuser'@'localhost' IDENTIFIED BY 'password';
mysql> GRANT ALL PRIVILEGES ON * . * TO 'testuser'@'localhost';
mysql> \q

sudo apt-get install python-mysqldb
mysql -u testuser -p	(Now you are logged in as testuser user)

5. Migrate and Run

python manage.py migrate
# EC2 > security group > Edit inbound rules > Map: All traffic to Anywhere

python manage.py runserver 0.0.0.0:8000

# Visit:
http://35.154.65.141:8000/

5. Setup Gunicorn

Testing Gunicorn’s Ability to Serve the Project

gunicorn --bind 0.0.0.0:8000 blogpost.wsgi
Visit:
  http://public_ip:8000/

Setup Gunicorn systemd Service File

  1. Create a Gunicorn systemd Service File
# sudo vim /etc/systemd/system/gunicorn.service
# Add below line in 'gunicorn.service' file

[Unit]
Description=gunicorn daemon
After=network.target

[Service]
User=ubuntu
Group=www-data
WorkingDirectory=/home/ubuntu/Deployment-demo
ExecStart=/home/ubuntu/.virtualenvs/testenv/bin/gunicorn --workers 3 --bind 0.0.0.0:8000 blogpost.wsgi:application

[Install]
WantedBy=multi-user.target
  1. To Start the server and check the status
sudo systemctl start gunicorn
sudo service gunicorn status
  1. Enable the server to automatically restart on reboot
sudo systemctl enable gunicorn
  1. Check the Gunicorn process logs by typing
sudo journalctl -u gunicorn
  1. Restarting Gunicorn after pulling some changes
sudo systemctl restart gunicorn
  1. If you change rapawalk-server systemd service file, reload the daemon and restart the process by typing:
sudo systemctl daemon-reload
sudo systemctl restart gunicorn
  • Try
Visit:
  http://public_ip:8000/

5. Setup Nginx

  • sudo apt-get install nginx

6. Setup Postgres

7. Initial Server Setup with Ubuntu

  • Will ignore this for now

Reference