Share it on social media

Table of contents

Published: March 7, 2022 Last modified: May 29, 2022

How to serve multiple Django projects with multiple domain names with Nginx and gunicorn on Ubuntu

There are many tutorials and articles on the internet that covers the deployment of a Django project on a VPS using NGINX and GUNICORN, but I didn't find one that covers deploying multiple Django websites in one VPS server. So in this article, we will see how to use the power of Nginx and Gunicorn to deploy multiple Django apps with multiple domains.



Prerequisites


I'm assuming that you already know how to set up a VPS server on a Linux operating system, if you don't I wrote an article that covers that in detail.

In short, we will use the following components

 →  Nginx
 
→  Virtualenv
 
→  Gunicorn
 
→  nano (text editor)


My working directory is "/home/selmi/", so the user is "selmi". Make sure to stay on the right track when it comes to using paths and users.


Note: In this guide, we will demonstrate how to install our Django projects on ubuntu (some steps and tools might be different from other Linux distros).



Domain names


In this article, I'll use subdomains instead of top-level domains. I have created two subdomains on my NeamCheap account from my top-level domain [selmi.tech]

The subdomains are:
→ coffee.selmi.tech
→ pacman.selmi.tech
The process of using the subdomains or top-level domains is the same with unnoticeable differences.
The only thing that you need to take care of is that the domains are connected to the VPS you have. For that, I created two A-type DNS records that point to my VPS IP address.



Django apps



I already have two Django projects ready to deploy. Very simple apps that display two pages. They have no media or static files but the process will be the same.

→ Project 1: Simple Coffee page
→ Project 2: Pacman animation




Both projects have the same structure


├── PacMan.png
├── config
│   ├── __init__.py
│   ├── __pycache__
│   ├── asgi.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── db.sqlite3
├── manage.py
├── pacman
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── migrations
│   ├── models.py
│   ├── tests.py
│   ├── urls.py
│   └── views.py
├── requirements.txt
└── templates
    └── home.html



Clone the projects and create a virtual environment



I'll use the following commands to install the two Django projects on the working directory.


selmi@vps2588:$ pwd

/home/selmi

selmi@vps2588:$ sudo git clone https://github.com/SelmiAbderrahim/pacman

selmi@vps2588:$ sudo git clone https://github.com/SelmiAbderrahim/coffee

selmi@vps2588:$ ls

pacman coffee




The projects share the same folder structure and the same packages. So I'll create one virtual environment for both of them. For more about installing virtual environments on VPS, read this article.

Make sure you have Nginx installed on your OS.


selmi@vps2588:$ sudo apt install nginx



To use the Python virtual environment, we will use the virtualenv module, install it using the following command:


selmi@vps2588:$ python -m pip install virtualenv

selmi@vps2588:$ python -m pip virtualenv pacman-coffee-env

selmi@vps2588:$ source pacman-coffee-env/bin/activate


By using the last command, we activated the virtual environment of these two projects. which means we are ready to install the dependencies.


Now, I'll install the projects' packages with pip:


(pacman-coffee-env) selmi@vps2588:$ python -m pip install -r pacman/requirements.txt



Setup Gunicorn for two Django projects


So far our projects are ready and our virtual environment is activated. The next step is installing Gunicorn.

(pacman-coffee-env)  selmi@vps2588:$ python -m pip install gunicorn



And to make sure everything is installed properly:


(pacman-coffee-env)  selmi@vps2588:$ gunicorn version
gunicorn (version 20.1.0)



Gunicorn for the first project (coffee)


Let's first create the socket file

(pacman-coffee-env) selmi@vps2588:$ sudo nano /etc/systemd/system/coffee.socket



Paste this inside of that file then Ctrl+x to save it.
[Unit]

Description=gunicorn socket

[Socket]

ListenStream=/run/coffee.sock

[Install]

WantedBy=sockets.target



Then to use that socket file, we need to create the service that starts gunicorn for this particular Django app with this particular socket file.


(pacman-coffee-env) selmi@vps2588:$ sudo nano /etc/systemd/system/coffee.service



Content:



[Unit]

Description=gunicorn daemon

Requires=coffee.socket

After=network.target

[Service]

User=selmi

Group=www-data

WorkingDirectory=/home/selmi/coffee

ExecStart=/home/selmi/pacman-coffee-env/bin/gunicorn --workers 3 --bind unix:/run/coffee.sock config.wsgi:application


[Install]

WantedBy=multi-user.target


After we save our files, With that, we can now start the Gunicorn service we created and enable it so that it starts at boot


(pacman-coffee-env) selmi@vps2588:$ sudo systemctl start coffee.socket

(pacman-coffee-env) selmi@vps2588:$ sudo systemctl enable coffee.socket


And we repeat the same process for the pacman project.


Gunicorn for the second project (pacman)

Let's first create the socket file

(pacman-coffee-env) selmi@vps2588:$ sudo nano /etc/systemd/system/pacman.socket



Paste this inside of that file then Ctrl+x to save it.
[Unit]

Description=gunicorn socket

[Socket]

ListenStream=/run/pacman.sock

[Install]

WantedBy=sockets.target


Then to use that socket file, we need to create the service that starts gunicorn for this particular Django app with this particular socket file.


 (pacman-coffee-env) selmi@vps2588:$ sudo nano /etc/systemd/system/pacman.service



[Unit]

Description=gunicorn daemon

Requires=pacman.socket

After=network.target

[Service]

User=selmi

Group=www-data

WorkingDirectory=/home/selmi/pacman

ExecStart=/home/selmi/pacman-coffee-env/bin/gunicorn --workers 3 --bind unix:/run/pacman.sock config.wsgi:application


[Install]

WantedBy=multi-user.target

After we save our files, With that, we can now start the Gunicorn service we created and enable it so that it starts at boot


(pacman-coffee-env) selmi@vps2588:$ sudo systemctl start pacman.socket

(pacman-coffee-env) selmi@vps2588:$ sudo systemctl enable pacman.socket



Confirm the status of the Gunicorn Socket Files


After we finished the previous step, we can see whether the operation was done successfully or not.



(pacman-coffee-env) selmi@vps2588:$ sudo systemctl status coffee.service


Output:


 coffee.service - gunicorn daemon  
      Loaded: loaded (/etc/systemd/system/coffee.service; enabled; vendor preset: enabled)

Active: active (running) since Fri 2022-03-04 15:53:56 UTC; 3 days ago




Also, we can check for the existence of the .sock file. Let's check for the pacman service now:


Also, we can check for the existence of the .sock file.

Let's check for the pacman service now:

(pacman-coffee-env) selmi@vps2588:$ sudo ls/run

Output:


... pacman.sock



Configure Nginx to Proxy Pass to Gunicorn



The next step is to set up Nginx to pass traffic to the process. What we will do is creating new files in the Nginx folder, each file contains the server records for each Django app.


Nginx for coffee project



We start by creating a new server block in Nginx’s sites-available folder.


selmi@vps2588:$ sudo nano /etc/nginx/sites-available/pacman



Content:


server {

listen 80;

server_name coffee.selmi.tech;


location = /favicon.ico { access_log off; log_not_found off; }


location / {

include proxy_params;

proxy_pass http://unix:/run/coffee.sock;

}

}


Then save and close the file with Ctrl+x once you are done. Next, we need to enable the file by linking it to the sites-enabled directory:


selmi@vps2588:$ sudo ln -s /etc/nginx/sites-available/pacman /etc/nginx/sites-enabled



Nginx for pacman project



We start by creating a new server block in Nginx’s sites-available folder.


 selmi@vps2588:$ sudo nano /etc/nginx/sites-available/pacman

Content:


server {

listen 80;

server_name pacman.selmi.tech;


location = /favicon.ico { access_log off; log_not_found off; }


location / {

include proxy_params;

proxy_pass http://unix:/run/pacman.sock;

}

}


Then save and close the file with Ctrl+x once you are done. Next, we need to enable the file by linking it to the sites-enabled directory:


selmi@vps2588:$ sudo ln -s /etc/nginx/sites-available/pacman /etc/nginx/sites-enabled


Finally, we need to restart nginx:


selmi@vps2588:$ sudo systemctl restart nginx


By checking if Nginx is running as we want, we can know that everything is up and running and ready to see the final result.


selmi@vps2588:$ sudo nginx -t


Output:



nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Conclusion


Now, both of the two projects are live now and we can check if they're working or not.

pacman project

coffee project



750 1
Selmitech

This is Selmi Abderrahim, the author and the admin of SelmiTech blog.

Subscribe to our mail list

Indara

7 months ago

Such amazing job, shouldn't I add the www. version of my domain name in the nginx server part?

Replies (1)

Selmitech

7 months ago

For top-level domains, yes you can. But not for subdomains