📋 Cheat Sheets

Nginx Cheat Sheet — Config Syntax, Common Setups, and Troubleshooting


Click any item to expand the explanation and examples.

🔧 Commands

nginx CLI cli
# Test config (always do this before reload!)
nginx -t

Reload config (no downtime)

sudo nginx -s reload

Start / stop

sudo systemctl start nginx sudo systemctl stop nginx sudo systemctl restart nginx

Check status

sudo systemctl status nginx

View error log

tail -f /var/log/nginx/error.log

View access log

tail -f /var/log/nginx/access.log

Config file locations

/etc/nginx/nginx.conf (main config)

/etc/nginx/sites-available/ (site configs)

/etc/nginx/sites-enabled/ (symlinks to active sites)

/etc/nginx/conf.d/ (additional configs)

🌐 Server Blocks

Basic static site config
server {
    listen 80;
    server_name example.com www.example.com;
    root /var/www/example.com;
    index index.html;
location / {
    try_files $uri $uri/ =404;
}

}

Reverse proxy (Node, Python, etc.) config
server {
    listen 80;
    server_name api.example.com;
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;
}

}

See also: 502 Bad Gateway fix for when the proxy can’t reach your app.

🔒 SSL / HTTPS

SSL with Let's Encrypt ssl
# Install certbot
sudo apt install certbot python3-certbot-nginx

Get certificate (auto-configures Nginx)

sudo certbot —nginx -d example.com -d www.example.com

Auto-renewal (usually set up automatically)

sudo certbot renew —dry-run

Manual SSL config

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;

# Modern SSL settings
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;

# HSTS
add_header Strict-Transport-Security "max-age=63072000" always;

}

HTTP → HTTPS redirect ssl
server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://$server_name$request_uri;
}

🔀 Redirects & Rewrites

Redirects redirect
# Permanent redirect (301)
location /old-page {
    return 301 /new-page;
}

www to non-www

server { listen 80; server_name www.example.com; return 301 https://example.com$request_uri; }

Redirect all to one page

location / { return 302 /maintenance.html; }

Rewrite (internal, URL stays the same in browser)

rewrite ^/blog/(.*)$ /articles/$1 last;

Trailing slash

rewrite ^([^.]*[^/])$ $1/ permanent;

📁 Location Blocks

Location matching rules location
# Prefix match (default)
location /images/ {
    root /var/www;
}

Exact match (highest priority)

location = /favicon.ico { log_not_found off; access_log off; }

Regex match (case sensitive)

location ~ .php$ { # handle PHP }

Regex match (case insensitive)

location ~* .(jpg|jpeg|png|gif|ico)$ { expires 30d; add_header Cache-Control “public, immutable”; }

Priority order:

1. = (exact)

2. ^~ (prefix, no regex check)

3. ~ or ~* (regex)

4. prefix (longest match)

⚡ Performance

Caching and compression perf
# Gzip compression
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml;
gzip_min_length 1000;

Static file caching

location ~* .(css|js|jpg|jpeg|png|gif|ico|svg|woff2)$ { expires 1y; add_header Cache-Control “public, immutable”; access_log off; }

Rate limiting

limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;

location /api/ { limit_req zone=api burst=20 nodelay; proxy_pass http://localhost:3000; }

File upload size

client_max_body_size 50M;

🔍 Common Patterns

SPA (React, Vue, Angular) pattern
server {
    listen 80;
    server_name app.example.com;
    root /var/www/app/dist;
    index index.html;
# All routes → index.html (client-side routing)
location / {
    try_files $uri $uri/ /index.html;
}

# Cache static assets
location /assets/ {
    expires 1y;
    add_header Cache-Control "public, immutable";
}

}

CORS headers pattern
location /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";
if ($request_method = OPTIONS) {
    return 204;
}

proxy_pass http://localhost:3000;

}

See also: CORS error fix