Skip to main content

Nginx Command Cheatsheet

Nginx is a high-performance web server and reverse proxy, known for its concurrency handling, low memory footprint, and flexible configuration syntax. This cheatsheet covers the most commonly used Nginx configuration directives — location block matching, SSL/TLS setup, reverse proxy, caching strategies, URL rewriting, load balancing, and logging. Start with location and proxy directives, then gradually explore SSL and caching.

Updated: 2026-07-16·42 commands

Quick Reference

TaskDirective
Static file servingroot /var/www/html; + index index.html;
URL redirectreturn 301 https://$host$request_uri;
Reverse proxyproxy_pass http://backend;
Load balancingupstream backend { server ...; }
HTTPS configlisten 443 ssl; + ssl_certificate
URL rewriterewrite ^/old/(.*)$ /new/$1 permanent;
Rate limitinglimit_req zone=mylimit burst=10;
Enable cachingproxy_cache mycache;
Access controlallow 192.168.1.0/24; deny all;
Config validationnginx -t

Location Matching

``nginx # Exact match (highest priority) location = / { return 200 "Welcome to root!\n"; }

# Exact match for specific path location = /favicon.ico { log_not_found off; access_log off; }

# Prefix match with ^~ (stops regex checking) location ^~ /static/ { root /var/www; expires 30d; }

# Regex match (case-sensitive) location ~ \.php$ { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; include fastcgi_params; }

# Regex match (case-insensitive) location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ { root /var/www; expires max; add_header Cache-Control "public, immutable"; }

# Regular prefix match (longest wins) location /api/ { proxy_pass http://api_backend; }

location / { root /var/www/html; index index.html; }

# Named location (internal redirect, not exposed) location @fallback { proxy_pass http://backend; }

# Nested location location /app/ { location ~ \.php$ { fastcgi_pass unix:/var/run/php.sock; } }

# Alias path mapping location /images/ { alias /data/uploads/; # /images/foo.jpg -> /data/uploads/foo.jpg }

# Access control location /admin/ { allow 192.168.1.0/24; allow 10.0.0.0/8; deny all; }

# try_files combination location / { try_files $uri $uri/ /index.html; # SPA fallback } `

SSL/TLS Configuration

`nginx # HTTPS server basic config server { listen 443 ssl http2; server_name example.com;

ssl_certificate /etc/nginx/ssl/example.com.pem; ssl_certificate_key /etc/nginx/ssl/example.com.key;

# Protocols and ciphers ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384; ssl_prefer_server_ciphers on;

# DH parameters (improved security) ssl_dhparam /etc/nginx/ssl/dhparam.pem;

# HSTS (force HTTPS) add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

# OCSP Stapling ssl_stapling on; ssl_stapling_verify on; resolver 8.8.8.8 8.8.4.4 valid=300s; resolver_timeout 5s;

# Session cache ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; ssl_session_tickets off; }

# HTTP -> HTTPS redirect server { listen 80; server_name example.com www.example.com; return 301 https://$host$request_uri; }

# Mutual TLS (client certificate auth) server { listen 443 ssl; ssl_client_certificate /etc/nginx/ssl/ca.crt; ssl_verify_client on; ssl_verify_depth 2;

location / { if ($ssl_client_verify != SUCCESS) { return 403; } proxy_pass http://backend; } }

# Let's Encrypt auto-renewal location ^~ /.well-known/acme-challenge/ { root /var/www/html; } `

Reverse Proxy

`nginx # Basic reverse proxy location / { proxy_pass http://127.0.0.1:3000; proxy_http_version 1.1;

# Forward client information 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_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; }

# WebSocket proxy location /ws/ { proxy_pass http://ws_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; # Long connection timeout }

# Path rewrite + proxy location /app/ { rewrite ^/app/(.*)$ /$1 break; proxy_pass http://app_server; # Avoids /app/foo -> /app/foo (removes prefix) }

# Proxy buffer control location /api/ { proxy_pass http://api_server; proxy_buffering on; proxy_buffer_size 4k; proxy_buffers 8 4k; proxy_busy_buffers_size 8k; proxy_max_temp_file_size 0; }

# Timeout settings location /slow/ { proxy_pass http://slow_backend; proxy_connect_timeout 10s; proxy_read_timeout 30s; proxy_send_timeout 30s; }

# Error page override location / { proxy_pass http://backend; proxy_intercept_errors on; error_page 502 503 504 /50x.html; } `

Caching

`nginx # Define cache zone (in http block) proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=mycache:10m max_size=1g inactive=60m use_temp_path=off;

# Backend cache control proxy_cache_key "$scheme$request_method$host$request_uri"; proxy_cache mycache;

# Cache TTL by response code proxy_cache_valid 200 302 60m; proxy_cache_valid 301 24h; proxy_cache_valid 404 1m; proxy_cache_valid any 5m;

# Cache bypass proxy_cache_bypass $http_cache_control; proxy_no_cache $http_pragma $http_authorization;

# Cache locking (prevents cache stampede) proxy_cache_lock on; proxy_cache_lock_timeout 5s;

# Cache hit debugging add_header X-Cache-Status $upstream_cache_status;

# Forward proxy cache location / { proxy_pass http://origin; proxy_cache public_cache; proxy_cache_valid 200 1h; proxy_cache_use_stale error timeout updating http_500 http_502 http_503;

# Cache purge (used with reverse proxy) location ~ /purge(/.*) { allow 127.0.0.1; deny all; proxy_cache_purge mycache "$scheme$request_method$host$1"; } }

# Per-parameter cache key proxy_cache_key "$scheme$host$request_uri$is_args$args";

# Micro-caching (for dynamic content) location / { proxy_cache micro; proxy_cache_valid 200 5s; proxy_cache_lock on; }

# FastCGI cache fastcgi_cache_path /data/nginx/fastcgi_cache levels=1:2 keys_zone=phpcache:10m max_size=1g inactive=60m; location ~ \.php$ { fastcgi_cache phpcache; fastcgi_cache_valid 200 60m; fastcgi_cache_methods GET HEAD; fastcgi_cache_use_stale error timeout updating; } `

URL Rewriting & Redirects

`nginx # Permanent redirect (301) rewrite ^/old-page$ /new-page permanent; rewrite ^/category/(.*)$ /shop/category/$1 permanent;

# Temporary redirect (302) rewrite ^/temp$ /temporary redirect;

# Internal rewrite (URL unchanged) rewrite ^/articles/(\d+)$ /show.php?id=$1 last; rewrite ^/user/([a-z]+)$ /profile.php?name=$1 last;

# Protocol redirect if ($scheme != "https") { return 301 https://$server_name$request_uri; }

# Remove www if ($host ~* ^www\.(.*)) { set $host_no_www $1; return 301 $scheme://$host_no_www$request_uri; }

# Add www if ($host !~* ^www\.) { return 301 $scheme://www.$host$request_uri; }

# Strip tracking parameters if ($args ~* "utm_source|utm_medium|utm_campaign") { return 301 $scheme://$host$uri; }

# Trailing slash handling rewrite ^([^.]*[^/])$ $1/ permanent;

# File extension mapping location ~ \.php$ { rewrite ^(.*)$ /index.php?$1 last; }

# Custom error pages error_page 404 /404.html; error_page 500 502 503 504 /50x.html; location = /50x.html { root /var/www/html; } `

Upstream & Load Balancing

`nginx # HTTP load balancing upstream backend { # Default: round robin server 192.168.1.10:3000 weight=3 max_fails=3 fail_timeout=30s; server 192.168.1.11:3000 weight=2 max_fails=3 fail_timeout=30s; server 192.168.1.12:3000 backup; # Backup server server unix:/var/run/app.sock; # Unix Socket

keepalive 32; # Connection pool }

# IP Hash session persistence upstream sticky_backend { ip_hash; server 192.168.1.10:3000; server 192.168.1.11:3000; }

# Least connections upstream least_conn_backend { least_conn; server 192.168.1.10:3000; server 192.168.1.11:3000; }

# Random strategy upstream random_backend { random two least_conn; server 192.168.1.10:3000; server 192.168.1.11:3000; server 192.168.1.12:3000; }

# Health checks (passive via max_fails + fail_timeout) # Active health checks require nginx-plus (commercial)

# Canary release (weight-based traffic split) upstream canary { server 192.168.1.10:3000 weight=90; # Stable 90% server 192.168.1.20:3000 weight=10; # Canary 10% }

# Map-based traffic routing map $cookie_user $backend_group { default backend; ~^admin admin_backend; }

# Upstream timeout and retry location / { proxy_pass http://backend; proxy_next_upstream error timeout invalid_header http_500 http_502 http_503; proxy_next_upstream_timeout 10s; proxy_next_upstream_tries 3; } `

Logging

`nginx # Custom log format http { log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"';

# JSON format (for log analysis tools) log_format json escape=json '{' '"time_local":"$time_local",' '"remote_addr":"$remote_addr",' '"remote_user":"$remote_user",' '"request":"$request",' '"status":$status,' '"body_bytes_sent":$body_bytes_sent,' '"request_time":"$request_time",' '"http_referrer":"$http_referer",' '"http_user_agent":"$http_user_agent",' '"http_x_forwarded_for":"$http_x_forwarded_for"' '}';

# Cache hit/miss log log_format cache '$remote_addr - $upstream_cache_status [$time_local] "$request" $status'; }

# Access logs access_log /var/log/nginx/access.log main; access_log /var/log/nginx/json.log json;

# Error log error_log /var/log/nginx/error.log warn;

# Per-site logs server { access_log /var/log/nginx/example.com.access.log main buffer=32k flush=5s; error_log /var/log/nginx/example.com.error.log error; }

# Disable logging for specific locations location = /health { access_log off; return 200 "OK\n"; }

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

# Conditional logging map $status $loggable { ~^[23] 0; # Skip 2xx and 3xx default 1; # Log everything else } access_log /var/log/nginx/error_only.log main if=$loggable;

# Log rotation (triggered by nginx -s reopen) # Use with logrotate: # /var/log/nginx/*.log { # daily # rotate 30 # compress # postrotate # [ ! -f /var/run/nginx.pid ] || kill -USR1 cat /var/run/nginx.pid # endscript # }

# Request body limits client_body_buffer_size 128k; client_max_body_size 10m;

# Debug logging (enable only when troubleshooting) # error_log /var/log/nginx/debug.log debug; ``

Location(8)

CommandLevel
location = /path { ... }
Exact URI match (highest priority)
Basic
location ^~ /path/ { ... }
Prefix match that stops regex checking after match
Intermediate
location ~ pattern { ... }
Regex match (case-sensitive)
Intermediate
location ~* pattern { ... }
Regex match (case-insensitive)
Intermediate
location /path/ { ... }
Regular prefix match (longest match wins)
Basic
location @name { ... }
Named location (internal redirect, not exposed externally)
Intermediate
alias <path>
Map request path to a different filesystem path
Intermediate
try_files $uri $uri/ /index.html
Try files/directories in order, fallback to last argument
Basic

SSL/TLS(7)

CommandLevel
listen 443 ssl http2
Listen on port 443 with SSL and HTTP/2 enabled
Basic
ssl_certificate / ssl_certificate_key
Specify SSL certificate and private key file paths
Basic
ssl_protocols TLSv1.2 TLSv1.3
Specify allowed SSL/TLS protocol versions (disable old ones)
Intermediate
ssl_ciphers <cipher_list>
Specify allowed SSL cipher suites
Expert
add_header Strict-Transport-Security
Enable HSTS to force browser HTTPS access
Intermediate
ssl_session_cache shared:SSL:10m
Configure SSL session cache (reduces repeated handshakes)
Intermediate
return 301 https://$host$request_uri
Automatic HTTP to HTTPS redirect
Basic

Reverse Proxy(5)

CommandLevel
proxy_pass <url>
Forward the request to a backend server
Basic
proxy_set_header <field> <value>
Set HTTP headers forwarded to the backend
Basic
proxy_http_version 1.1
Set proxy HTTP protocol version (required for WebSocket)
Intermediate
proxy_read_timeout 30s
Set proxy read timeout
Intermediate
proxy_intercept_errors on
Intercept backend error codes and show custom error pages
Intermediate

Caching(5)

CommandLevel
proxy_cache_path <path> <options>
Define cache storage path and parameters
Expert
proxy_cache <zone>
Enable proxy cache and specify cache zone name
Intermediate
proxy_cache_valid 200 302 60m
Set cache TTL by response status code
Intermediate
proxy_cache_bypass <condition>
Specify conditions for bypassing the cache
Intermediate
add_header X-Cache-Status $upstream_cache_status
Add cache hit/miss status to response headers (debugging)
Intermediate

Rewrite(7)

CommandLevel
rewrite ^/old$ /new permanent
Permanent redirect (301)
Basic
rewrite ^/temp$ /temporary redirect
Temporary redirect (302)
Basic
rewrite ^/path/(.*)$ /new/$1 last
Internal URL rewrite (browser URL unchanged)
Intermediate
return 301 https://$server_name$request_uri
Return a specific status code and redirect URL
Basic
if ($scheme != "https") { ... }
Conditional block (used in rewrites)
Intermediate
error_page 404 /404.html
Custom error page configuration
Basic
rewrite ^([^.]*[^/])$ $1/ permanent
Automatically add a trailing slash
Intermediate

Upstream(5)

CommandLevel
upstream name { server ...; }
Define an upstream server group (backend pool)
Basic
server <address> weight=<n>
Add a backend server with weight in upstream block
Intermediate
server <address> backup
Set as backup server (used only when all primary servers are down)
Intermediate
ip_hash
Enable IP hash load balancing (session persistence)
Intermediate
least_conn
Enable least connections load balancing strategy
Intermediate

Logging(5)

CommandLevel
log_format <name> <format>
Define a custom log format
Intermediate
access_log <file> <format>
Configure access log file path and format
Basic
error_log <file> <level>
Configure error log file path and severity level
Basic
access_log off
Disable access logging for a specific location
Basic
client_max_body_size <size>
Set the maximum client request body size
Basic

FAQ

This cheatsheet is compiled from official tool documentation. Last updated: 2026-07-16.