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