Skip to content

Nginx Configuration

Nginx serves as a reverse proxy for Dharini, routing traffic to the appropriate Docker containers and handling SSL termination.

Install Nginx on your EC2 instance:

Terminal window
sudo apt-get update
sudo apt-get install -y nginx

Enable and start Nginx:

Terminal window
sudo systemctl enable nginx
sudo systemctl start nginx

Nginx configuration files are located in:

  • /etc/nginx/sites-available/ - Available site configurations
  • /etc/nginx/sites-enabled/ - Enabled site configurations (symlinks)

Create a new site configuration:

Terminal window
sudo nano /etc/nginx/sites-available/dharini-prod

This configuration routes different paths to different services:

server {
server_name in.dharini.artpark.ai;
# Frontend - Main application
location / {
proxy_pass http://YOUR_PRIVATE_IP:3000/;
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;
}
# Redirect /api to /api/docs
location = /api {
return 301 /api/docs;
}
# Backend API
location /api/ {
proxy_pass http://YOUR_PRIVATE_IP:4000/;
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;
}
# APK Download Server
location /download/ {
proxy_pass http://YOUR_PRIVATE_IP:3001/;
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;
}
listen 80;
}

Important Notes:

  1. Path Stripping: The configuration above strips the path prefix when forwarding:

    • Client request: in.dharini.artpark.ai/api/users
    • Backend receives: /users
  2. Private IP: Replace YOUR_PRIVATE_IP with your EC2 instance’s private IP

  3. API Root Redirect: The /api location redirects to /api/docs (Swagger documentation) to avoid showing a broken URL

  4. Port Mapping:

    • :3000 - Frontend (Next.js)
    • :4000 - Backend (NestJS API)
    • :3001 - APK Server

Alternative configuration using subdomains:

# Frontend
server {
server_name in.dharini.artpark.ai;
location / {
proxy_pass http://YOUR_PRIVATE_IP:3000/;
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;
}
listen 80;
}
# API
server {
server_name api.in.dharini.artpark.ai;
location / {
proxy_pass http://YOUR_PRIVATE_IP:4000/;
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;
}
listen 80;
}
# APK Downloads
server {
server_name download.in.dharini.artpark.ai;
location / {
proxy_pass http://YOUR_PRIVATE_IP:3001/;
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;
}
listen 80;
}

Create a symlink to enable the site:

Terminal window
sudo ln -s /etc/nginx/sites-available/dharini-prod /etc/nginx/sites-enabled/

Test the configuration:

Terminal window
sudo nginx -t

If the test passes, reload Nginx:

Terminal window
sudo systemctl reload nginx

Install Certbot:

Terminal window
sudo apt-get install -y certbot python3-certbot-nginx

Generate SSL certificates:

Terminal window
# For path-based routing (single domain)
sudo certbot --nginx -d in.dharini.artpark.ai
# For subdomain-based routing (multiple domains)
sudo certbot --nginx -d in.dharini.artpark.ai -d api.in.dharini.artpark.ai -d download.in.dharini.artpark.ai

Certbot will automatically:

  • Generate SSL certificates
  • Update Nginx configuration
  • Set up automatic renewal

Your configuration will be updated to:

server {
server_name in.dharini.artpark.ai;
location / {
proxy_pass http://YOUR_PRIVATE_IP:3000/;
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;
}
# Redirect /api to /api/docs
location = /api {
return 301 /api/docs;
}
location /api/ {
proxy_pass http://YOUR_PRIVATE_IP:4000/;
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;
}
location /download/ {
proxy_pass http://YOUR_PRIVATE_IP:3001/;
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;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/in.dharini.artpark.ai/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/in.dharini.artpark.ai/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
# HTTP to HTTPS redirect
server {
if ($host = in.dharini.artpark.ai) {
return 301 https://$host$request_uri;
} # managed by Certbot
server_name in.dharini.artpark.ai;
listen 80;
return 404; # managed by Certbot
}

Certbot sets up automatic renewal via cron. Test renewal:

Terminal window
sudo certbot renew --dry-run

For handling large file uploads:

server {
# ... existing config ...
client_max_body_size 100M;
location /api/media/upload {
proxy_pass http://172.31.6.216:4000/api/media/upload;
client_max_body_size 100M;
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;
# Timeouts for large uploads
proxy_read_timeout 300;
proxy_connect_timeout 300;
proxy_send_timeout 300;
}
}

If you need WebSocket support:

location /ws/ {
proxy_pass http://172.31.6.216:4000/ws/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
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;
}

Protect against abuse:

# Define rate limit zone
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
server {
# ... existing config ...
location /api/ {
limit_req zone=api_limit burst=20 nodelay;
proxy_pass http://YOUR_PRIVATE_IP:4000/;
# ... other proxy settings ...
}
}

Custom log format:

log_format detailed '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'$request_time';
server {
access_log /var/log/nginx/dharini-access.log detailed;
error_log /var/log/nginx/dharini-error.log warn;
# ... rest of config ...
}
Terminal window
sudo nginx -t
Terminal window
# Access logs
sudo tail -f /var/log/nginx/access.log
# Error logs
sudo tail -f /var/log/nginx/error.log
Terminal window
sudo systemctl reload nginx
Terminal window
sudo systemctl restart nginx
Terminal window
sudo systemctl status nginx

Add security headers to your configuration:

server {
# ... existing config ...
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always;
}