Swipe left or right to navigate to next or previous post

This blog post is about how to install Django with Nginx as server and Supervisor for process control and Gunicorn as Python WSGI HTTP Server. We will be using the Ubuntu OS. Basic understanding of the python/Django and Linux environment is needed to follow along the tutorial. The steps to setup is similar in all the cloud services. However, following steps are based on AWS ec2
sudo apt update && sudo apt upgrade -y
sudo apt install python3-dev gcc libssl-dev virtualenv supervisor nginx gunicorn -y
Clone the project git. For the tutorial purpose, we have the project on the /home/ubuntu/api folder.
git clone github_url
virtualenv venv -p python3
-p python3 parameter is used to set the python3 interpreter.
source venv/bin/activate
pip3 install -r requirements.txt
I have the environment file env.example.py inside separate folder in config/settings.
sudo cp config/settings/env.example.py config/settings/env.py
sudo nano config/settings/env.py
Most of the project have .env.example file in the root folder of the project. Copy and update the file
sudo cp .env.example .env
sudo nano .env
logs folder is required to store the logs files. media files is used to store the uploaded files and static folder is used to store the static files of the project. The folder for logs, static files and media and folder can be configured in env file.
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR,'static')
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
mkdir logs static media
python manage.py collectstatic
We need to create the various folder for the gunicorn and supervisor. For this tutorial purpose, we create these folders along side the project folder inside /home/ubuntu/
mkdir bin logs run
touch /home/ubuntu/logs/gunicorn-error.log
You can choose the mysql or the postgres database based on your choice
sudo apt install mysql-server libmysqlclient-dev default-libmysqlclient-dev -y
sudo systemctl start mysql && sudo systemctl enable mysql
sudo mysql_secure_installation utility
sudo mysql
CREATE USER 'project_user'@'localhost' IDENTIFIED BY 'password';
create database myproject_db character set utf8mb4;
grant all privileges on project_user.* to 'myproject_db'@'localhost' identified by 'password';
sudo apt-get install python3-pip python3-dev libpq-dev postgresql postgresql-contrib -y
sudo systemctl enable supervisor && sudo systemctl start supervisor
sudo -u postgres createuser project_user;
sudo -u postgres createdb myproject_db;
sudo -u postgres psql;
alter user 'project_user' with encrypted password 'password';
grant all privileges on database 'myproject_db' to 'project_user';
sudo service postgresql stop
sudo service postgresql start
sudo service postgresql restart
source venv/bin/activate
python manage.py makemigrations
python manage.py migrate
Create a gunicorn_start file inside the /home/ubuntu/bin
sudo nano bin/gunicorn_start
#!/bin/bash
NAME="project_name"
DIR=/home/ubuntu/api
USER=ubuntu
GROUP=ubuntu
WORKERS=3
BIND=unix:/home/ubuntu/run/gunicorn.sock
DJANGO_SETTINGS_MODULE=config.settings
DJANGO_WSGI_MODULE=config.wsgi
LOG_LEVEL=error
cd $DIR
source venv/bin/activate
export DJANGO_SETTINGS_MODULE=$DJANGO_SETTINGS_MODULE
export PYTHONPATH=$DIR:$PYTHONPATH
exec venv/bin/gunicorn ${DJANGO_WSGI_MODULE}:application \
--name $NAME \
--workers $WORKERS \
--user=$USER \
--group=$GROUP \
--bind=$BIND \
--log-level=$LOG_LEVEL \
--log-file=-
DJANGO_SETTINGS_MODULE and DJANGO_WSGI_MODULE path must be with respect to project. Since my all the settings are inside config folder, so all its value start from config.
Later on, while running the gunicorn, if you see the path error. Please use the absolute folder from the root. like \home\USER_NAME\YOUR_PROJECT_NAME
sudo chmod u+x bin/gunicorn_start
Supervisor is used to monitor and control a number of process running in unix based operating system.
Create new file inside /etc/supervisor/conf.d . For the sake of tutorials purpose, we are using the myproject.conf
sudo nano /etc/supervisor/conf.d/myproject.conf
sudo nano /etc/supervisor/conf.d/myproject.conf
[program:myproject]
command=sh /home/ubuntu/bin/gunicorn_start
user=ubuntu
autostart=true
autorestart=true
redirect_stderr=true
stdout_logfile=/home/ubuntu/logs/gunicorn-error.log
You can change the path to gunicorn_start if you store the file in different location. Update the username according to the user
Following command helps to reread and update the currently updated supervisor commands
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl status myproject
If we can see the myproject running and uptime, then everything is
sudo nano /etc/nginx/sites-available/myproject.conf
upstream app_server {
server unix:/home/ubuntu/run/gunicorn.sock fail_timeout=0;
}
server {
listen 80;
# add here the ip address of your server
# or a domain pointing to that ip (like example.com or www.example.com)
# You can add the multiple server_name with http, https and www
server_name test.com;
# server_name test.com http.test.com https.test.com www.test.com;
keepalive_timeout 5;
client_max_body_size 4G;
access_log /home/ubuntu/logs/nginx-access.log;
error_log /home/ubuntu/logs/nginx-error.log;
location /static/ {
alias /home/ubuntu/api/static/;
}
location /media/ {
alias /home/ubuntu/api/media/;
}
# checks for static file, if not found proxy to app
location / {
try_files $uri @proxy_to_app;
}
location @proxy_to_app {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://app_server;
}
}
sudo nginx -t
sudo ln -s /etc/nginx/sites-available/myproject.conf /etc/nginx/sites-enabled/
sudo rm /etc/nginx/sites-enabled/default
sudo systemctl restart nginx
sudo systemctl restart supervisor
Check the nginx error
sudo nginx -c /etc/nginx/nginx.conf -t
sudo nginx -t
Reload and Restart supervision
sudo supervisorctl reload
sudo supervisorctl restart myproject
Some useful Supervisor commands
sudo nano gunicorn_start
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl status myproject