Pardeep Dhiman
5 min readApr 17, 2022

deploy django with gunicorn and nginx

How to deploy multiple django applications with gunicorn and nginx

In this article,I will explain how you can deploy Multiple Django applications on one Nginx server with Gunicorn as wsgi server

Before Starting I assume that

- you have uploaded your Django applications folders to your server
- python3 installed on Server
- basic essentials installed for python3
- you have earlier deployed with Nginx and Gunicorn because I am not covering all basics to deploy Django application.Although with this tutorial you can learn deployment .

Note

I will use two Django applications for tutorial

First application name : django_one
Second application name : django_two

These both applications have basic code but this tutorial works on all kind of Django code.
Before deploying make sure you have requirements.txt file in your code

In this tutorial,I have

- used root as user (Not Recommended ,You should separate user for it)
- deployed and tested on Ubuntu 18 LTS,20 LTS and Centos 7,8
- used Python3.8 and Django 4.0 for deployment
- used default database sqlite3

Lets Start

On server ,your uploaded project folder path in most cases will be

/home/user/<your-project-folder>
or
/home/<your-project-folder>

In this tutorial it will be /home/multiple_django/django_one django_two

Step 1

Create virtual environment in both folders separately

$ pwd
/home/multiple_django

For First Django application(django_one)

$ cd django_one
$ virtualenv -p python3.8 env
$ source env/bin/activate
(env)$ pip install -r requirements.txt
(env)$ pip install gunicorn

after installing all packages ,run runserver command .Kindly allow required firewall permissions to 8000 port

(env) $ python manage.py runserver 0.0.0.0:8000

you can visit http://server_ip:8000 to check the code running in browser

Congratulations, You have done basic setup to run Django Application,Just deactivate virtual environment and follow above step for second Django application (django_two)

For Second Django application(django_two)

$ cd django_two
$ virtualenv -p python3.8 env
$ source env/bin/activate
(env)$ pip install -r requirements.txt
(env)$ pip install gunicorn

after installing all packages ,run runserver command .Kindly allow required firewall permissions to 8000 port

(env) $ python manage.py runserver 0.0.0.0:8000

you can visit http://server_ip:8000 to check the code running in browser

Congratulations, You have done basic setup to run both Django Applications

Creating systemd Socket and Service Files for Gunicorn

For Django First Application (django_one)

Step 1: Create socket file for django_one application. It is same as creating gunicorn.socket but with different name just

$ sudo vim /etc/systemd/system/django_one.socket

Paste given below content in above file

[Unit]
Description=Django One socket
[Socket]
ListenStream=/run/django_one.sock
[Install]
WantedBy=sockets.target

Step 2: Create service file for django_one application. It is same as creating gunicorn.service but with different configurations

$ sudo vim /etc/systemd/system/django_one.service

Paste given below content in above file

[Unit]
Description=Django one daemon
Requires=django_one.socket
After=network.target
[Service]
User=root
Group=nginx
WorkingDirectory=/home/multiple_django/django_one
ExecStart=/home/multiple_django/django_one/env/bin/gunicorn \
— access-logfile — \
— workers 3 \
— bind unix:/run/django_one.sock \
core.wsgi:application
[Install]
WantedBy=multi-user.target

Now run given below commands to activate socket and service

$ sudo systemctl start django_one.socket
$ sudo systemctl start django_one.service
$ sudo systemctl enable django_one.socket
$ sudo systemctl enable django_one.service
# To check Status
$ sudo systemctl status django_one

If everything works fine ,you will see status active in status.if anything doesn’t works fine debug according to it or change user and group in .service file

Congratulations,you have configured gunicorn service for first django application.

For Django Second Application (django_two)

Step 1: Create socket file for django_two application. It is same as creating gunicorn.socket but with different name just

$ sudo vim /etc/systemd/system/django_two.socket

Paste given below content in above file

[Unit]
Description=Django Two socket
[Socket]
ListenStream=/run/django_two.sock
[Install]
WantedBy=sockets.target

Step 2: Create service file for django_two application. It is same as creating gunicorn.service but with different configurations

$ sudo vim /etc/systemd/system/django_two.service

Paste given below content in above file

[Unit]
Description=Django two daemon
Requires=django_two.socket
After=network.target
[Service]
User=root
Group=nginx
WorkingDirectory=/home/multiple_django/django_two
ExecStart=/home/multiple_django/django_two/env/bin/gunicorn \
— access-logfile — \
— workers 3 \
— bind unix:/run/django_two.sock \
core.wsgi:application
[Install]
WantedBy=multi-user.target

Now run given below commands to activate socket and service

$ sudo systemctl start django_two.socket
$ sudo systemctl start django_two.service
$ sudo systemctl enable django_two.socket
$ sudo systemctl enable django_two.service
# To check Status
$ sudo systemctl status django_two

If everything works fine ,you will see status active in status.if anything doesn’t works fine debug according to it or change user and group in .service file

Congratulations,you have configured gunicorn service for second django application.

Configure NGINX File

In my learning i have found two ways of configuring nginx files for django applications.you can try any one way to run your application

Process 1 :

For Django First Application(django_one)

$ sudo vim /etc/nginx/sites-available/django_one

paste given below content in above file

server {
listen 80;
server_name server_domain_or_IP_1;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/multiple_django/django_one;
}
location / {
include proxy_params;
proxy_pass http://unix:/run/django_one.sock;
}
}

Now run these commands to activate your nginx. Make sure you have allowed required firewall permissions to nginx

$ sudo ln -s /etc/nginx/sites-available/django_one /etc/nginx/sites-enabled
$ sudo systemctl restart nginx

Congratulations ,you have configured first application successfully. You can visit http://domain_or_IP_1 in browser to check the code working

For Django Second Application(django_two)

$ sudo vim /etc/nginx/sites-available/django_two

paste given below content in above file

server {
listen 80;
server_name server_domain_or_IP_2;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/multiple_django/django_two;
}
location / {
include proxy_params;
proxy_pass http://unix:/run/django_two.sock;
}
}

Now run these commands to activate your nginx. Make sure you have allowed required firewall permissions to nginx

$ sudo ln -s /etc/nginx/sites-available/django_two /etc/nginx/sites-enabled
$ sudo systemctl restart nginx

Congratulations ,you have configured first application successfully. You can visit http://domain_or_IP_2 in browser to check the code working

Process 2 :

In this process you can configure nginx settings for both or multiple applications in one file only.

There is key named server {} with all configurations which you required in nginx file.You can create multiple server{} to serve multiple django applications

$ sudo vim /etc/nginx/nginx.conf

create/paste these lines(for both applications)

server {
listen 80;
server_name server_domain_or_IP_1;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/multiple_django/django_one;
}
location / {
proxy_set_header Host $http_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-Proto $scheme;
proxy_pass http://unix:/run/django_one.sock;
}
}
server {
listen 80;
server_name server_domain_or_IP_2;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/multiple_django/django_two;
}
location / {
proxy_set_header Host $http_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-Proto $scheme;
proxy_pass http://unix:/run/django_two.sock;
}
}

After any updates run this command

$ sudo systemctl restart nginx

That’s it,You have deployed multiple django applications with gunicorn and nginx on one server

Bonus:

Youtube video link : https://youtu.be/hVPCQdgaF9I