Nginx serves as a reverse proxy, handling SSL, static files, and load balancing.
Basic Configuration
nginx# /etc/nginx/sites-available/myproject upstream django { server unix:/run/gunicorn/myproject.sock; # Or TCP: server 127.0.0.1:8000; } server { listen 80; server_name example.com www.example.com; # Redirect HTTP to HTTPS return 301 https://$server_name$request_uri; } server { listen 443 ssl http2; server_name example.com www.example.com; # SSL certificates ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256; ssl_prefer_server_ciphers off; # 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 Strict-Transport-Security "max-age=31536000; includeSubDomains" always; # Logging access_log /var/log/nginx/myproject_access.log; error_log /var/log/nginx/myproject_error.log; # Max upload size client_max_body_size 10M; # Static files location /static/ { alias /var/www/myproject/staticfiles/; expires 1y; add_header Cache-Control "public, immutable"; } # Media files location /media/ { alias /var/www/myproject/media/; expires 1M; add_header Cache-Control "public"; } # Django app 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_redirect off; proxy_pass http://django; } }
Enable Site
bash# Create symbolic link sudo ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled/ # Test configuration sudo nginx -t # Reload Nginx sudo systemctl reload nginx
SSL with Let's Encrypt
bash# Install Certbot sudo apt install certbot python3-certbot-nginx # Obtain certificate sudo certbot --nginx -d example.com -d www.example.com # Auto-renewal (usually set up automatically) sudo certbot renew --dry-run
Load Balancing
nginxupstream django { least_conn; # Load balancing method server 127.0.0.1:8001 weight=3; server 127.0.0.1:8002; server 127.0.0.1:8003 backup; }
WebSocket Support (for ASGI)
nginxlocation /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_pass http://django; }
Rate Limiting
nginx# In http block limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s; # In location block location /api/ { limit_req zone=api burst=20 nodelay; proxy_pass http://django; }