Cheatsheets / Nginx

Nginx Cheatsheet

Complete Nginx reference. Hit Ctrl+P to print.

Core Directives

user nginx;Worker process user
worker_processes auto;Number of worker processes — auto matches CPU count
worker_connections 1024;Max simultaneous connections per worker (inside events {})
events { worker_connections 1024; }events block — connection handling config
http { ... }http block — all web serving config lives here
include /etc/nginx/conf.d/*.conf;Include all .conf files from a directory
include mime.types;Load MIME type mappings
default_type application/octet-stream;Fallback MIME type for unknown extensions
sendfile on;Use kernel sendfile() for static files — more efficient
tcp_nopush on;Send headers in one packet — use with sendfile
tcp_nodelay on;Disable Nagle — reduces latency for small packets
keepalive_timeout 65;Seconds to keep idle client connections open
client_max_body_size 10m;Max request body size — 0 disables the limit
client_body_timeout 30;Seconds to wait for client to send request body
send_timeout 30;Seconds to wait between successive write ops to client
error_log /var/log/nginx/error.log warn;Error log path and level: debug|info|notice|warn|error|crit
access_log /var/log/nginx/access.log combined;Access log path and format name
access_log off;Disable access logging
pid /run/nginx.pid;Path for the master process PID file
gzip on;Enable gzip compression
gzip_types text/plain text/css application/json application/javascript;MIME types to compress
gzip_min_length 256;Only compress responses larger than N bytes

Server Blocks

server { listen 80; server_name example.com; }Basic server block
listen 80;Listen on port 80 (IPv4)
listen [::]:80;Listen on port 80 (IPv6)
listen 443 ssl;Listen on port 443 with SSL
listen 80 default_server;Default server — catches unmatched server_name requests
server_name example.com www.example.com;Match these hostnames
server_name *.example.com;Wildcard subdomain match
server_name ~^(?<sub>.+)\.example\.com$;Regex server name with named capture
root /var/www/html;Document root for this server
index index.html index.php;Default files to serve for directory requests
error_page 404 /404.html;Custom error page
error_page 500 502 503 504 /50x.html;Multiple error codes to one page
return 301 https://$host$request_uri;Redirect HTTP to HTTPS
server_tokens off;Hide Nginx version from error pages and headers

Location Matching

location / { }Prefix match — matches any URI starting with /
location = /exact { }= exact match — highest priority, stops searching
location ^~ /static/ { }^~ prefix match — stops regex searching if matched
location ~ \.php$ { }~ case-sensitive regex match
location ~* \.(jpg|png|gif)$ { }~* case-insensitive regex match
location @named { }Named location — only for internal redirects
try_files $uri $uri/ /index.html;Try each path in order, serve last as fallback
try_files $uri $uri/ =404;Return 404 if nothing found
try_files $uri @fallback;Fall back to named location
alias /var/www/other/;Serve from a different path than root
expires 30d;Set Cache-Control and Expires headers
expires -1;Disable caching (no-cache)
add_header Cache-Control "public, max-age=2592000";Manually set cache header
internal;Location only accessible via internal redirects, not clients

Reverse Proxy

proxy_pass http://127.0.0.1:8080;Forward request to upstream server
proxy_pass http://127.0.0.1:8080/app;Forward with a path prefix added
proxy_pass http://backend;Forward to upstream group named "backend"
proxy_http_version 1.1;Use HTTP/1.1 for keep-alive support
proxy_set_header Host $host;Forward original Host header
proxy_set_header X-Real-IP $remote_addr;Forward client IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;Append client IP to forwarded-for chain
proxy_set_header X-Forwarded-Proto $scheme;Forward http or https scheme
proxy_set_header Upgrade $http_upgrade;Required for WebSocket proxying
proxy_set_header Connection "upgrade";Required for WebSocket proxying
proxy_read_timeout 60s;Max time to wait for upstream response
proxy_connect_timeout 10s;Max time to establish connection to upstream
proxy_send_timeout 60s;Max time between successive writes to upstream
proxy_buffering off;Disable buffering — stream response directly to client
proxy_buffer_size 4k;Buffer size for first part of upstream response
proxy_cache_bypass $http_cache_control;Skip cache if header is set
proxy_hide_header X-Powered-By;Remove header from upstream before sending to client

SSL / TLS

listen 443 ssl;Enable SSL on port 443
ssl_certificate /etc/ssl/certs/cert.pem;Path to certificate (full chain)
ssl_certificate_key /etc/ssl/private/key.pem;Path to private key
ssl_protocols TLSv1.2 TLSv1.3;Allowed TLS versions — drop TLSv1.0/1.1
ssl_ciphers HIGH:!aNULL:!MD5;Allowed cipher suites
ssl_prefer_server_ciphers on;Use server cipher preference over client
ssl_session_cache shared:SSL:10m;Shared SSL session cache — 10 MB holds ~40k sessions
ssl_session_timeout 1d;How long SSL sessions can be reused
ssl_session_tickets off;Disable session tickets — improve forward secrecy
ssl_stapling on; ssl_stapling_verify on;Enable OCSP stapling — faster certificate validation
resolver 1.1.1.1 valid=300s;DNS resolver for OCSP stapling
add_header Strict-Transport-Security "max-age=63072000" always;HSTS — force HTTPS for 2 years
add_header X-Frame-Options DENY;Prevent clickjacking
add_header X-Content-Type-Options nosniff;Prevent MIME-type sniffing

Rewrites & Redirects

return 301 https://$host$request_uri;Permanent redirect (301)
return 302 /new-path;Temporary redirect (302)
return 200 "OK";Return status with body
return 404;Return status with no body
rewrite ^/old/(.*)$ /new/$1 permanent;Rewrite URL with regex — permanent = 301
rewrite ^/old/(.*)$ /new/$1 redirect;Rewrite URL — redirect = 302
rewrite ^/old/(.*)$ /new/$1 last;Rewrite then re-search location blocks
rewrite ^/old/(.*)$ /new/$1 break;Rewrite then stop processing rewrites
if ($host != "example.com") { return 301 https://example.com$request_uri; }Redirect non-canonical domains
if ($request_method = POST) { ... }Condition on request method
$uri / $request_uri$uri is decoded and normalised; $request_uri is original
$host / $http_host$host is server_name; $http_host includes port if non-standard
$scheme"http" or "https"
$remote_addr / $remote_portClient IP address / port
$args / $arg_nameFull query string / specific query param
$request_method / $statusHTTP method (GET, POST...) / response status code

Load Balancing

upstream backend { server 10.0.0.1:8080; server 10.0.0.2:8080; }Round-robin upstream group (default)
least_conn;Route to server with fewest active connections
ip_hash;Route by client IP — sticky sessions
hash $request_uri consistent;Route by URI — consistent hashing
server 10.0.0.1:8080 weight=3;Weight — server receives 3x more requests
server 10.0.0.1:8080 backup;Backup — only used when all primary servers are down
server 10.0.0.1:8080 down;Mark server as permanently unavailable
server 10.0.0.1:8080 max_fails=3 fail_timeout=30s;Passive health check — mark failed after 3 errors in 30s
keepalive 32;Keep N idle upstream connections open per worker
zone backend 64k;Shared memory zone for upstream state (required for health checks)
nginx -tTest configuration for syntax errors
nginx -s reloadReload config without dropping connections
nginx -s stop / nginx -s quitFast stop / graceful shutdown
nginx -VShow version and compiled-in modules