How to Configure Nginx for Every Major Framework
As a vibe coder, you've built something amazing with AI assistance. Your app works perfectly in development, but now you need to deploy it to production. Enter Nginx - the battle-tested web server that'll handle your traffic like a boss.
Whether you're shipping a Next.js masterpiece, a Django API, or a Vue SPA, getting Nginx configured correctly can make or break your deployment. Let's dive into the most common framework configurations so you can ship with confidence.
Why Nginx Rules the Deployment Game
Before we jump into configs, here's why Nginx is your production best friend:
- Performance: Handles thousands of concurrent connections efficiently
- SSL Termination: Let Nginx handle HTTPS so your app doesn't have to
- Load Balancing: Distribute traffic across multiple instances
- Static File Serving: Blazing fast delivery of assets
- Reverse Proxy: Perfect for Node.js, Python, and other backend frameworks
React/Vue/Angular SPAs
Single Page Applications need special handling for client-side routing. Here's the golden configuration:
server {
listen 80;
server_name your-domain.com;
root /var/www/your-spa/build;
index index.html;
# Handle client-side routing
location / {
try_files $uri $uri/ /index.html;
}
# Cache static assets aggressively
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# Security headers
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
}
The magic is in try_files $uri $uri/ /index.html - this ensures all routes fall back to your main HTML file for client-side routing to work.
Next.js Applications
Next.js apps run on Node.js, so you need a reverse proxy setup:
server {
listen 80;
server_name your-nextjs-app.com;
# Proxy to Next.js
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_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_cache_bypass $http_upgrade;
}
# Handle Next.js static files directly
location /_next/static/ {
alias /var/www/your-app/.next/static/;
expires 1y;
add_header Cache-Control "public, immutable";
}
}
Express.js/Node.js APIs
For pure API servers, keep it simple:
server {
listen 80;
server_name api.your-domain.com;
location / {
proxy_pass http://localhost: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;
}
# CORS headers for API
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS";
add_header Access-Control-Allow-Headers "Authorization, Content-Type";
}
Django Applications
Django with uWSGI or Gunicorn needs this setup:
server {
listen 80;
server_name your-django-app.com;
# Serve static files directly
location /static/ {
alias /var/www/your-app/staticfiles/;
expires 1y;
}
# Serve media files
location /media/ {
alias /var/www/your-app/media/;
}
# Proxy to Django app
location / {
proxy_pass http://localhost: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;
}
}
Flask Applications
Flask apps are lightweight but still need proper proxying:
server {
listen 80;
server_name your-flask-app.com;
location / {
proxy_pass http://localhost:5000;
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;
}
# Handle static files if needed
location /static/ {
alias /var/www/your-app/static/;
expires 30d;
}
}
Laravel/PHP Applications
PHP apps need FastCGI handling:
server {
listen 80;
server_name your-laravel-app.com;
root /var/www/your-app/public;
index index.php;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
}
# Security: deny access to .htaccess files
location ~ /\.ht {
deny all;
}
}
Universal SSL Configuration
Once you have your basic config working, add SSL for any framework:
server {
listen 80;
server_name your-domain.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name your-domain.com;
ssl_certificate /path/to/your/cert.pem;
ssl_certificate_key /path/to/your/private.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384;
# Your framework-specific config goes here
}
Pro Tips for Production
1. Enable Gzip Compression
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css text/xml text/javascript application/javascript application/json;
2. Set Up Rate Limiting
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
location /api/ {
limit_req zone=api burst=20 nodelay;
# ... rest of config
}
3. Health Check Endpoint
location /health {
access_log off;
return 200 "OK\n";
add_header Content-Type text/plain;
}
The DeployMyVibe Advantage
Configuring Nginx correctly is crucial, but it's just one piece of the deployment puzzle. At DeployMyVibe, we handle all this configuration (and more) automatically:
- Framework detection and optimal Nginx setup
- Automatic SSL certificate provisioning
- Performance optimization out of the box
- Health monitoring and alerting
- Zero-downtime deployments
You focus on building amazing apps with AI assistance. We handle the DevOps complexity.
Wrapping Up
Nginx configuration doesn't have to be a deployment bottleneck. With these battle-tested configs, you can get your AI-built apps running smoothly in production. Remember to test your configuration with nginx -t before reloading, and always keep your SSL certificates up to date.
Ready to ship your next vibe-coded masterpiece? These Nginx configurations will get you there. Happy deploying!
Alex Hackney
DeployMyVibe