Nginx Cheatsheet
Location Blocks
Use this Nginx reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.
Syntax
location [modifier] uri { ... }Modifier Reference
| Modifier | Type | Behaviour |
|---|---|---|
| (none) | Prefix | Matches if URI starts with the string |
= | Exact | Matches only if URI is exactly equal |
^~ | Priority prefix | Best prefix match; skips regex if matched |
~ | Regex (case-sensitive) | PCRE regex |
~* | Regex (case-insensitive) | PCRE regex, ignores case |
@ | Named | Internal redirect target only (no client requests) |
Matching Priority Order
=exact match (stops immediately)^~longest prefix match (stops — no regex checked)- Regex matches in config file order (first match wins)
- Longest prefix match (no modifier)
location = /favicon.ico { ... } # 1 — exact, checked first
location ^~ /static/ { ... } # 2 — prefix, skips regex
location ~* \.(jpg|png|gif)$ { ... } # 3 — regex
location / { ... } # 4 — catch-all prefixCommon Patterns
# Exact match — fast for high-traffic single URIs location = /health { default_type text/plain; # add_header cannot set Content-Type on return bodies return 200 "ok"; } # Prefix — all URIs under /api/ location /api/ { proxy_pass http://backend; } # Priority prefix — skip regex for static assets location ^~ /assets/ { root /var/www; expires 1y; } # Case-insensitive regex — image files anywhere location ~* \.(png|jpg|jpeg|gif|webp|svg)$ { root /var/www; expires 30d; } # Named location — used with error_page or try_files location @fallback { proxy_pass http://backend; }
try_files Patterns
# Static site: file → directory index → 404 try_files $uri $uri/ =404; # SPA: fall through to index.html try_files $uri $uri/ /index.html; # Proxy fallback: serve file if it exists, else pass to backend try_files $uri @backend; location @backend { proxy_pass http://app_server; }
Nested Locations
location /app/ {
root /var/www;
location ~* \.php$ { # Nested: only runs for .php under /app/
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}Avoid deep nesting — it's hard to reason about priority.
Internal Locations
# Only reachable via internal redirects (error_page, try_files, X-Accel-Redirect) location /private/ { internal; root /data/protected; } # Use with X-Accel-Redirect from an upstream app # App returns: X-Accel-Redirect: /private/file.pdf
Basic Auth
# Create the password file (htpasswd ships in apache2-utils / httpd-tools) sudo htpasswd -c /etc/nginx/.htpasswd admin # -c only the first time
location /admin/ {
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/.htpasswd;
}
# Combine with an IP allowlist — satisfy any = pass EITHER check
location /internal/ {
satisfy any;
allow 10.0.0.0/8;
deny all;
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/.htpasswd;
}Restricting Methods
location /api/ {
limit_except GET POST {
deny all;
}
}Per-location Logging Control
location /health {
access_log off; # Suppress health-check noise
return 200;
}
location ~* \.(css|js|png)$ {
access_log /var/log/nginx/static.log; # Separate log for assets
}Returning Responses Directly
location = /robots.txt { return 200 "User-agent: *\nDisallow: /admin/\n"; }
location = /ping { return 200 "pong"; }
location /old-path/ { return 301 /new-path/; }
location /gone/ { return 410; }