
Sanjay Sikdar
Today I'm gonna share how to Install and Configure Django / Django Rest Framework with Nginx and I am using AWS EC2 (t3.micro) for writing this tutorial.
First, we require an ec2 instance so launch an instance with your preferred size, you can also attach an Elastic IP to your instance.
In your DNS Server (Route 53 or Cloudflare) add these records.
| Record Name | Record Type | Value |
|---|---|---|
| @ | A | [Server_IP] |
| www | CNAME | example.com |
Now, we have pointed from our DNS to our new server IP, now we need to log in into our new server using SSH client.
Example: ssh -i "YourKey.pem" ubuntu@SERVER_IP
Set a Timezone on Ubuntu:
sudo timedatectl set-timezone Asia/Kolkata && sudo timedatectlIf first time using apt in this session, run the update command to update the package manager cache:
sudo apt update && sudo apt -y upgradeInstall Basic Requirements:
# Python 3.10
sudo apt install python3.10-venv -y && sudo apt install python3-pip -y && sudo apt install libpq-dev nginx curl
# Python 3.12
sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt-get install python3.12-venv -y && sudo apt install python3-pip -y && sudo apt-get install python3-tk -y && sudo apt-get install python3.12-dev -y && sudo apt install libpq-dev nginx curl
# Python 3.14
sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt install -y python3.14 python3.14-venv python3.14-tk python3.14-dev \
libpq-dev nginx curl
python3.14 -m ensurepip --upgrade
python3.14 -m pip install --upgrade pip setuptools wheel
After installing, you can request to your domain (http://example.com), You will get nginx default page as response.
Install Redis (optional)
sudo apt install redis-server
sudo systemctl status redis
redis-cli ping
# In not started
sudo systemctl start redis
sudo systemctl enable redisIf you are using any third party database like RDS then you can skip this step.
Create a Postgres database for Django application; so execute the following command on command line to create database for Django / DRF app:
Installing Requirements:
sudo apt install postgresql postgresql-contrib
sudo -u postgres psqlCreating Database and User:
CREATE DATABASE myproject;
CREATE USER myprojectuser WITH PASSWORD 'password';
ALTER ROLE myprojectuser SET client_encoding TO 'utf8';
ALTER ROLE myprojectuser SET default_transaction_isolation TO 'read committed';
ALTER ROLE myprojectuser SET timezone TO 'UTC';
GRANT ALL PRIVILEGES ON DATABASE myproject TO myprojectuser;
\qCreating a new Django project or Clone from Github/GitLab
You can set up the git into your server following this Link (OPTIONAL)
Generate SSH Key on Server:
ssh-keygen -o
cat /home/ubuntu/.ssh/id_rsa.pub # Ubuntu 22.04
cat /home/ubuntu/.ssh/id_ed25519.pub. # Ubuntu 24.04Clone App from GitHub:
cd /home/ubuntu
git clone https://github.com/sannjayy/drf-simple-task-tracker.gitCreating Virtual Environment and Setup Project Requirements:
cd drf-simple-task-tracker
python3 -m venv zenv
source zenv/bin/activate
pip install -r requirements.txt
python manage.py makemigrations
python manage.py migrate
python manage.py createsuperuser
python manage.py collectstaticMake sure you have installed gunicorn and whitenoise in your env.
Testing Server:
python manage.py runserver 0.0.0.0:8000Request on http://example.com:8000
Creatinggunicorn.socket
sudo nano /etc/systemd/system/gunicorn.socketPaste Following:
[Unit]
Description=gunicorn socket
[Socket]
ListenStream=/run/gunicorn.sock
[Install]
WantedBy=sockets.targetCreatinggunicorn.service
sudo nano /etc/systemd/system/gunicorn.serviceReplace theproject directory and project.wsgi location as your project name:
[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target
[Service]
User=ubuntu
Group=www-data
WorkingDirectory=/home/ubuntu/drf-simple-task-tracker
ExecStart=/home/ubuntu/drf-simple-task-tracker/zenv/bin/gunicorn \
--access-logfile - \
--workers 3 \
--timeout 600 \
--bind unix:/run/gunicorn.sock \
project.wsgi:application
[Install]
WantedBy=multi-user.targetEnable the Gunicorn:
sudo systemctl start gunicorn.socket
sudo systemctl enable gunicorn.socket
sudo systemctl status gunicorn.socketTest Gunicorn:
sudo systemctl status gunicorn
curl --unix-socket /run/gunicorn.sock localhost
sudo systemctl status gunicornReplace theproject name as your project:
sudo nano /etc/nginx/sites-available/project_nameChange the path/home/ubuntu/drf-simple-task-tracker and Copy, and paste the following Nginx Configuration:
server {
server_name example.com www.example.com;
client_max_body_size 100M;
charset utf-8;
underscores_in_headers on;
# access_log /home/ubuntu/drf-simple-task-tracker/logs/nginx-access.log;
error_log /home/ubuntu/drf-simple-task-tracker/logs/nginx-error.log;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
alias /home/ubuntu/drf-simple-task-tracker/static/staticfiles/;
}
location /media/ {
root /home/ubuntu/drf-simple-task-tracker;
client_max_body_size 100M;
}
location / {
include proxy_params;
proxy_connect_timeout 600;
proxy_send_timeout 600;
proxy_read_timeout 600;
send_timeout 600;
proxy_pass http://unix:/run/gunicorn.sock;
}
}Enable the configuration:
sudo ln -s /etc/nginx/sites-available/project_name /etc/nginx/sites-enabled
sudo nginx -t
sudo systemctl restart nginx
sudo systemctl status nginxNow you can request domain http://example.com and your site should be visible.
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d example.com -d www.example.com
sudo systemctl status certbot.timer
sudo certbot renew --dry-runNow you can request the website using https://example.com.
For restarting the Nginx and pulling Code from Git, I have created a shell script.
sudo nano /usr/local/bin/zFor creating the shell script, modify copy, and paste the following code to your terminal.
#!/bin/bash
select opt in Sync Restart ChangeDir CleanUp CheckStatus Quit
do
case $opt in
Sync)
cd /home/ubuntu/drf-simple-task-tracker
git pull origin master
echo "Code Synchronized!"
exit 0
;;
Restart)
sudo nginx -t && sudo systemctl restart nginx
sudo systemctl restart gunicorn
# sudo systemctl restart daphne.service
echo "Nginx & gunicorn has been restarted."
exit 0
;;
ChangeDir)
cd /home/ubuntu/drf-simple-task-tracker
echo -e '\nHit [Ctrl]+[D] to exit this child shell.'
$SHELL
exit 0
;;
CleanUp)
redis-cli flushall
redis-cli flushdb
echo "Cleaned up Redis!"
sudo apt clean
sudo rm -rf /tmp/*
sudo apt autoclean
sudo rm /var/log/*.gz
sudo journalctl --vacuum-size=50M
sudo apt autoremove --purge
echo "System Cleaned up"
exit 0
;;
CheckStatus)
echo "--> GUNICORN"
sudo systemctl status gunicorn
echo "--> NGINX"
sudo systemctl status nginx
echo "--> STORAGE"
df -h
echo "--> Shell by SanjaySikdar.Dev <--"
exit 0
;;
Quit)
echo "Exited!"
exit 0
;;
*)
echo "invalid option"
;;
esac
donesudo chmod +x /usr/local/bin/zNow press the z key and hit enter.
ubuntu@ip-172-31-0-94:~$ z
1) Sync
2) Restart
3) ChangeDir
4) CheckStatus
5) Quit
#?Select any option by pressing the number keys.
Hope you guys like the article. If you encounter any difficulties in understanding this approach, please don't hesitate to leave a comment.
Bind the port 9001
daphne -b 0.0.0.0 -p 9001 project.asgi:applicationCreate Daphne Service
sudo nano /etc/systemd/system/daphne.service[Unit]
Description=daphne service
After=network.target
[Service]
Type=simple
User=ubuntu
Group=www-data
WorkingDirectory=/home/ubuntu/drf-simple-task-tracker
ExecStart=/home/ubuntu/drf-simple-task-tracker/zenv/bin/daphne -p 9001 project.asgi:application
Restart=on-failure
[Install]
WantedBy=multi-user.targetStart Service
sudo systemctl daemon-reload
sudo systemctl start daphne.service
sudo systemctl status daphne.service
sudo systemctl enable daphne.serviceUpdate Nginx File:
# Place Here
upstream channels-backend {
server localhost:9001;
}
server {
location / { }
# Place Here
location /ws/ {
proxy_pass http://0.0.0.0:9001;
proxy_http_version 1.1;
proxy_read_timeout 86400;
proxy_redirect off;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
}Restart
sudo systemctl restart daphne.serviceIf nginx getting 403-Forbidden > sudo gpasswd -a www-data ubuntu
Other Permission Issue > sudo chmod +x /home/ubuntu/projectdir
Restart Deamon > sudo systemctl daemon-reload
Installing mysqlclient - Click here
Generate SECRET_KEY > openssl rand -base64 64
__pycache__ folders and migration files# Remove all __pycache__ directories
find . -type d -name "__pycache__" -exec rm -rf {} +
# Remove migration files except in the zenv folder
find . -type d -name zenv -prune -o -type f -path "*/migrations/*" ! -name "__init__.py" -exec rm -f {} +