Django Deployment Using Gunicorn, Nginx
This is for anyone who wants to deploy their Django project on the cloud using Gunicorn and Nginx. I have listed the steps down.
1) Login as root to the server instance through ssh:
ssh -i PEM_FILE root@IP
2) Do an update to the system:
apt-get update -y
3) Install PIP 3:
apt-get install python3-pip -y
3) Install Nginx:
apt-get install nginx -y
4) Update pip and install virtualenv:
sudo -H pip3 install — upgrade pip
sudo -H pip3 install virtualenv
5) Create a project directory and change the path to the new directory:
mkdir ~/<project_name>
cd ~/<project_name>
6) Create a virtualenv:
virtualenv venv
7) Activate virtualenv:
source venv/bin/activate
8) Clone the Django project git repo:
git clone <repo_url>
9) Install all requirements for the project from the requirements.txt file:
pip3 install -r requirements.txt
10) Run the below command and check on the browser using server IP with port 8000 from the browser to make sure it is working:
python manage.py runserver 0.0.0.0:8000
11) Install Gunicorn if not installed already using the below command:
apt install gunicorn
12) Check step #10 again with Gunicorn and if it is working again just to make sure all looks fine:
gunicorn — bind 0.0.0.0:8000 <project_name>.wsgi:application
13) Create a Systemd Service file for Gunicorn. Listed down the steps for that:
A) Use this command:
nano /etc/systemd/system/gunicorn.service
B) Add the below lines with changes appropriate to the project
[Unit]
Description=gunicorn daemon
After=network.target
[Service]
User=root
Group=root
WorkingDirectory=/root/<path_to_project_directory>/
ExecStart=/root/<path_to_project_directory>/venv/bin/gunicorn — access-logfile — — workers 3 — bind unix:/root/<path_to_project_directory>/server.sock <project_name>.wsgi:application
[Install]
WantedBy=multi-user.target
C) Start and enable Gunicorn service to start on boot time with the below commands:
systemctl start gunicorn
systemctl enable gunicorn
D) You can check the status of the gunicorn service using the below command:
systemctl status gunicorn
14) Configure Nginx. Steps are listed down.
A) Change the user www-data to root on Nginx config
nano /etc/nginx/nginx.conf
Use the above command and change the user on the first line. So that the file permissions are appropriate
B) Create a config file for Nginx with the below command:
nano /etc/nginx/sites-available/<site_name>
C) Add the following lines:
server {
listen 8000;
server_name <server_ip_or_domain_name>; ## Change the system public IP or domain from which we will access the site/ api
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /root/<path_to_project_root>;
}
location / {
include proxy_params;
proxy_pass http://unix:root/<path_to_project_directory>/server.sock;
}
}
access_log /root/<path_to_project_root>/nginx-access.log;
error_log /root/<path_to_project_root>/nginx-error.log;
D) Create a syslink:
ln -s /etc/nginx/sites-available/<site_name> /etc/nginx/sites-enabled/
E) Check if there is an error on the config by running the below command:
nginx -t
F) Restart Nginx:
systemctl restart nginx
Now we can access the site/ API, as usual, using server public IP or domain name (if configured). We have configured everything on the server.
For further changes on code, just pull the latest code to the git repo on the server, restart the gunicorn service using the below command and the changes will be reflected.
sudo service gunicorn restart
Please make sure to freeze the requirements file every time if there is a change/ new library installed and do a pip install -r requirements.txt after activating the virtualenv.