Introduction
Nginx is the most widely used reverse proxy and web server on the internet. Configuring it correctly is essential for performance, security, and scalability. This guide covers everything from basic setup to advanced production configurations.
Basic Reverse Proxy Configuration
Forward requests to a backend application: ```nginx server { listen 80; server_name api.example.com; location / { proxy_pass http://127.0.0.1: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; } } ```
SSL Termination with Let's Encrypt
Terminate SSL at the proxy level: ```nginx server { listen 443 ssl http2; server_name example.com; 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 on; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; location / { proxy_pass http://backend; } } ```
Load Balancing Multiple Backends
Distribute traffic across multiple application instances: ```nginx upstream backend { least_conn; # Send to server with fewest connections server 10.0.0.1:3000 weight=3 max_fails=3 fail_timeout=30s; server 10.0.0.2:3000 weight=2; server 10.0.0.3:3000 backup; # Only used if others fail } server { listen 80; server_name app.example.com; location / { proxy_pass http://backend; proxy_next_upstream error timeout invalid_header http_500; proxy_next_upstream_tries 3; } } ```
Caching Static Content
Improve performance with proxy caching: ```nginx proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=static:10m max_size=1g inactive=60m; server { location /static/ { proxy_cache static; proxy_cache_valid 200 60m; proxy_cache_valid 404 1m; add_header X-Cache-Status $upstream_cache_status; proxy_pass http://backend; } location / { proxy_cache_bypass $http_cache_control; proxy_no_cache $http_pragma $http_authorization; proxy_pass http://backend; } } ```
Rate Limiting
Protect your backends from abuse: ```nginx # Define rate limit zone limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s; limit_conn_zone $binary_remote_addr zone=addr:10m; server { location /api/ { limit_req zone=api_limit burst=20 nodelay; limit_conn addr 10; limit_conn_log_level warn; proxy_pass http://backend; } } ```
Security Headers
Essential security headers: ```nginx server { 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 "strict-origin-when-cross-origin" always; add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:;" always; add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always; # Hide Nginx version server_tokens off; } ```
WebSocket Support
For real-time applications: ```nginx location /ws/ { proxy_pass http://backend; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_read_timeout 86400s; # 24 hours for long-lived connections } ```
Monitoring & Logging
Structured logging with JSON: ```nginx http { log_format json escape=json '{"time":"$time_local",' '"remote_addr":"$remote_addr",' '"request":"$request",' '"status":$status,' '"body_bytes":$body_bytes_sent,' '"referer":"$http_referer",' '"user_agent":"$http_user_agent",' '"request_time":$request_time,' '"upstream_time":$upstream_response_time}'; access_log /var/log/nginx/access.json json; } ```
Conclusion
Nginx is incredibly versatile as a reverse proxy. Start with the basic configuration, add SSL, then progressively layer in caching, load balancing, rate limiting, and security headers. Monitor your logs to fine-tune performance.
Published on June 7, 2026 · Filed under DevOps
← Back to Blog