353 words
2 minutes
Deploying a Django Backend on an Azure VM with Gunicorn & Nginx
TIP

Deploying a Django application with Nginx and Gunicorn on Azure can be challenging, but this comprehensive guide will walk you through the process step by step. We’ll cover everything from setting up your server to securing it with SSL, ensuring your Django application runs efficiently in a production environment.

Setting Up the Server#

Update and Install Required Packages#

sudo apt update && sudo apt upgrade -y
sudo apt install python3-pip python3-venv nginx -y

Cloning the Django Project and Setting Up the Virtual Environment#

cd /home/azureuser

Clone the Project from GitHub#

git clone https://github.com/your-username/your-django-repo.git django-brevo
cd django-brevo

Create and Activate a Virtual Environment#

python3 -m venv venv
source venv/bin/activate

Install Dependencies#

pip install --upgrade pip
pip install -r requirements.txt

Configuring Django for Production#

Set Up Environment Variables (Optional)#

Create a .env file:

SECRET_KEY=your-secret-key
DEBUG=False
ALLOWED_HOSTS=yourdomain.com

Modify settings.py:

import os
from dotenv import load_dotenv
load_dotenv()

SECRET_KEY = os.getenv("SECRET_KEY")
DEBUG = os.getenv("DEBUG") == "True"
ALLOWED_HOSTS = os.getenv("ALLOWED_HOSTS").split(",")

Apply Migrations#

python manage.py migrate

Setting Up Gunicorn#

Test Gunicorn Locally#

gunicorn --workers 3 --bind 0.0.0.0:8000 backend.wsgi:application

Create a Systemd Service for Gunicorn#

sudo nano /etc/systemd/system/gunicorn.service

Paste the following configuration:

[Unit]
Description=Gunicorn Daemon for Django App
After=network.target

[Service]
User=azureuser
Group=www-data
WorkingDirectory=/home/azureuser/django-brevo
ExecStart=/home/azureuser/django-brevo/venv/bin/gunicorn --workers 3 --bind unix:/home/azureuser/django-brevo/gunicorn.sock backend.wsgi:application

[Install]
WantedBy=multi-user.target

Start and Enable Gunicorn#

sudo systemctl start gunicorn
sudo systemctl enable gunicorn

Check Gunicorn Status#

sudo systemctl status gunicorn

Setting Up Nginx as a Reverse Proxy#

Create Nginx Configuration File#

sudo nano /etc/nginx/sites-available/django-brevo

Paste the following configuration:

server {
    listen 80;
    server_name yourdomain.com;

    location / {
        proxy_pass http://unix:/home/azureuser/django-brevo/gunicorn.sock;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

Enable the Configuration#

sudo ln -s /etc/nginx/sites-available/django-brevo /etc/nginx/sites-enabled

Test Nginx Configuration#

sudo nginx -t

Restart Nginx#

sudo systemctl restart nginx

Enable Nginx to Start on Boot#

sudo systemctl enable nginx

Fixing Permission Issues#

Fix Gunicorn Socket Permissions#

sudo chown -R azureuser:www-data /home/azureuser/django-brevo
sudo chmod -R 750 /home/azureuser/django-brevo
sudo chown azureuser:www-data /home/azureuser/django-brevo/gunicorn.sock
sudo chmod 660 /home/azureuser/django-brevo/gunicorn.sock

Restart Services#

sudo systemctl restart gunicorn nginx

Verify Everything is Running#

sudo systemctl status gunicorn
sudo systemctl status nginx

Allow Traffic and Secure the Server#

Open Firewall Ports#

sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'
sudo ufw enable

Obtain SSL Certificate (Optional)#

If using a domain, install Certbot for free SSL via Let’s Encrypt:

sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com

Enable auto-renewal:

sudo certbot renew --dry-run

Monitoring and Debugging#

Check Logs for Issues#

Gunicorn logs:

sudo journalctl -u gunicorn --no-pager -f

Nginx error logs:

sudo tail -f /var/log/nginx/error.log
Deploying a Django Backend on an Azure VM with Gunicorn & Nginx
https://blogs.200630.xyz/posts/django-nginx/django-nginx-deployment/
Author
Marsal Soren
Published at
2025-02-12