DeveloperBootstrap

DevOps

Nginx Production Setup Guide

Configure Nginx for production with SSL/TLS, load balancing, reverse proxy, aggressive caching, rate limiting, and security headers.

What you'll learn

  • Install and configure Nginx on Ubuntu 24.04
  • Configure SSL/TLS with modern cipher suites
  • Set up reverse proxy for Node.js, Python, or PHP applications
  • Implement upstream load balancing
  • Configure gzip and brotli compression
  • Add rate limiting and connection throttling
  • Implement security headers and WAF rules

Installation

Bash
1sudo apt update && sudo apt install -y nginx
2sudo systemctl enable --now nginx
3sudo ufw allow 'Nginx Full'
4
5# Verify
6curl -I http://localhost   # HTTP 200
7nginx -v                   # nginx version

SSL/TLS Configuration

NGINX
1# /etc/nginx/conf.d/ssl-params.conf — shared SSL settings
2ssl_protocols TLSv1.3;
3ssl_prefer_server_ciphers off;
4ssl_session_cache   shared:SSL:10m;
5ssl_session_timeout 1d;
6ssl_session_tickets off;
7ssl_stapling         on;
8ssl_stapling_verify  on;
9resolver 8.8.8.8 8.8.4.4 valid=300s;
10resolver_timeout 5s;
11
12# Diffie-Hellman group
13openssl dhparam -out /etc/nginx/dhparam.pem 2048
14ssl_dhparam /etc/nginx/dhparam.pem;

Reverse Proxy

NGINX
1# /etc/nginx/sites-available/myapp
2server {
3    listen 80;
4    server_name myapp.example.com;
5    return 301 https://$host$request_uri;
6}
7
8server {
9    listen 443 ssl;
10    http2 on;
11    server_name myapp.example.com;
12
13    ssl_certificate     /etc/letsencrypt/live/myapp.example.com/fullchain.pem;
14    ssl_certificate_key /etc/letsencrypt/live/myapp.example.com/privkey.pem;
15    include /etc/nginx/conf.d/ssl-params.conf;
16
17    location / {
18        proxy_pass         http://127.0.0.1:3000;
19        proxy_http_version 1.1;
20        proxy_set_header   Upgrade    $http_upgrade;
21        proxy_set_header   Connection 'upgrade';
22        proxy_set_header   Host       $host;
23        proxy_set_header   X-Real-IP  $remote_addr;
24        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
25        proxy_set_header   X-Forwarded-Proto $scheme;
26        proxy_cache_bypass $http_upgrade;
27        proxy_read_timeout 60s;
28    }
29}

Load Balancing

NGINX
1# /etc/nginx/conf.d/upstream.conf
2upstream app_servers {
3    least_conn;                     # route to least-busy server
4    server 10.0.0.1:3000 weight=3; # primary — 3x traffic
5    server 10.0.0.2:3000 weight=1;
6    server 10.0.0.3:3000 backup;   # only used if primaries fail
7    keepalive 32;                   # persistent connections
8}
9
10server {
11    location / {
12        proxy_pass http://app_servers;
13    }
14}

Caching & Compression

NGINX
1# nginx.conf http block
2gzip on;
3gzip_comp_level 6;
4gzip_min_length 1000;
5gzip_types text/plain text/css application/json application/javascript
6           text/xml application/xml application/rss+xml image/svg+xml;
7
8# Proxy cache
9proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=app_cache:10m
10                 max_size=1g inactive=60m use_temp_path=off;
11
12# Server block
13location /api/ {
14    proxy_pass http://app_servers;
15    proxy_cache app_cache;
16    proxy_cache_key "$scheme$request_method$host$request_uri";
17    proxy_cache_valid 200 5m;
18    proxy_cache_valid 404 1m;
19    add_header X-Cache-Status $upstream_cache_status;
20}
21
22# Static assets with long cache
23location /assets/ {
24    root /var/www/myapp;
25    expires 1y;
26    add_header Cache-Control "public, immutable";
27}

Security & Rate Limiting

NGINX
1# Rate limiting zones (http block)
2limit_req_zone $binary_remote_addr zone=api:10m rate=20r/s;
3limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;
4limit_conn_zone $binary_remote_addr zone=addr:10m;
5
6# Apply in location blocks
7location /api/ {
8    limit_req zone=api burst=40 nodelay;
9    limit_conn addr 20;
10    proxy_pass http://app_servers;
11}
12
13location /api/auth/login {
14    limit_req zone=login burst=5;
15    proxy_pass http://app_servers;
16}
17
18# Security headers (server block)
19add_header X-Frame-Options "DENY" always;
20add_header X-Content-Type-Options "nosniff" always;
21add_header Referrer-Policy "strict-origin-when-cross-origin" always;
22add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
23add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
24
25# Test config before reload
26sudo nginx -t && sudo systemctl reload nginx