Nginx Reverse Proxy Setup for Node.js and Django
How to configure Nginx as a high-performance reverse proxy to route and manage traffic for multiple backend applications, including Node.js and Django.
When deploying modern backend applications to production, running web servers directly on privileged ports (like 80 or 443) or exposing internal application servers directly to the public internet introduces severe security risks and performance limitations. Node.js applications typically run on port 3000, while Python/Django applications execute behind WSGI/ASGI servers like Gunicorn or Uvicorn on ports like 8000.
To bridge this gap efficiently, **Nginx** acts as an industry-standard high-performance reverse proxy, load balancer, and SSL terminator. This comprehensive guide covers how to install, configure, and optimize Nginx to route traffic seamlessly across multiple Node.js and Django applications on a single cloud server.
1. Understanding the Reverse Proxy Architecture
A traditional forward proxy sits in front of clients to control outbound traffic, whereas a **reverse proxy** sits in front of backend servers, intercepting incoming client requests and forwarding them to the appropriate application instance.
- Security & Isolation: Backend application servers are safely hidden behind private local ports, protecting them from direct layer-4 attacks, DDoS spikes, and direct IP enumeration.
- SSL/TLS Termination: Nginx handles HTTPS encryption certificates (e.g., Let's Encrypt), decrypting incoming secure traffic before forwarding unencrypted HTTP requests to internal application servers.
- Static File Offloading: Nginx excels at serving static assets (CSS, JavaScript, images) directly from disk at lightning speed without waking up Node.js or Python runtime workers.
2. Installing Nginx and Preparing Application Servers
Let's install Nginx on a Ubuntu/Debian production server and ensure system firewall permissions are properly configured.
# Update package lists and install Nginx
sudo apt update
sudo apt install nginx -y
# Start and enable Nginx service
sudo systemctl start nginx
sudo systemctl enable nginx
# Adjust firewall to allow HTTP and HTTPS traffic
sudo ufw allow 'Nginx Full'
3. Configuring Nginx for a Node.js Application
Assume your Node.js Express application runs locally on `http://localhost:3000`. Create a new Nginx server block configuration file inside `/etc/nginx/sites-available/`.
server {
listen 80;
server_name api.codecrown.in;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host$host;
proxy_cache_bypass $http_upgrade;
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;
}
}
Enable the configuration by creating a symbolic link to `sites-enabled` and testing the syntax:
sudo ln -s /etc/nginx/sites-available/nodejs-app /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
4. Configuring Nginx for a Django Application
Django applications typically run behind Gunicorn on `http://localhost:8000`, requiring Nginx to forward both dynamic requests to Gunicorn and static/media files directly from disk.
server {
listen 80;
server_name django.codecrown.in;
# Serve static files directly
location /static/ {
alias /var/www/django_project/staticfiles/;
}
# Serve media uploads directly
location /media/ {
alias /var/www/django_project/media/;
}
# Proxy dynamic requests to Gunicorn
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $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;
}
}
5. Securing Domains with Free SSL Certificates (Certbot)
Encrypting your reverse proxy traffic using Let's Encrypt SSL certificates ensures secure HTTPS communication across all domains.
# Install Certbot and Nginx plugin
sudo apt install certbot python3-certbot-nginx -y
# Automatically obtain and configure SSL certificates for your domains
sudo certbot --nginx -d api.codecrown.in -d django.codecrown.in
Conclusion
Configuring Nginx as a reverse proxy for Node.js and Django applications provides robust security isolation, efficient SSL termination, and optimized static asset delivery. By centralizing traffic routing under Nginx, engineering teams can host multiple disparate backend stacks reliably on a single cloud infrastructure.