Nginx Configuration Cheatsheet
Master Nginx configuration for web serving, reverse proxying, and load balancing with practical, runnable examples.
## Quick Overview
Nginx (pronounced "engine-x") is a powerful, high-performance HTTP and reverse proxy server, as well as a mail proxy server and a generic TCP/UDP proxy server. It's renowned for its stability, rich feature set, simple configuration, and low resource consumption. Developers commonly reach for Nginx to serve static content, load balance traffic across multiple backend servers, cache responses, and act as a secure gateway for APIs or applications. This guide covers Nginx configurations from basic web serving to advanced proxying, focusing on version `1.25+`.
**Install (Ubuntu/Debian):**
```bash
# Update package list
sudo apt update
# Install Nginx
sudo apt install nginx
Getting Started
To get Nginx running and serving content, you typically install it, create a basic configuration file, and then start the service.
-
Install Nginx (if not already):
# For Debian/Ubuntu sudo apt update sudo apt install nginx # For RHEL/CentOS sudo yum install epel-release sudo yum install nginx -
Verify Nginx is Running:
# Check service status sudo systemctl status nginx # Expected output should show 'active (running)'If not running, start it:
sudo systemctl start nginxAccess
http://localhostin your browser. You should see the default Nginx welcome page. -
Basic Static File Server: Let’s create a simple HTML file and configure Nginx to serve it.
-
Create a simple
index.html:# Create a directory for our site sudo mkdir -p /var/www/my-app.com/html # Create an index.html file echo "<h1>Hello from my-app.com!</h1>" | sudo tee /var/www/my-app.com/html/index.html -
Create a new Nginx server block configuration file:
sudo nano /etc/nginx/sites-available/my-app.comAdd the following content:
# /etc/nginx/sites-available/my-app.com server { listen 80; # Listen for incoming HTTP requests on port 80 listen [::]:80; # Listen for IPv6 requests server_name my-app.com www.my-app.com; # Define the domain names this server block responds to root /var/www/my-app.com/html; # Set the document root for this server block index index.html index.htm; # Define default files to serve when a directory is requested location / { try_files $uri $uri/ =404; # Try to serve the requested file, then directory, otherwise return 404 } # Log files for this server block access_log /var/log/nginx/my-app.com-access.log; error_log /var/log/nginx/my-app.com-error.log; } -
Enable the site by symlinking it to
sites-enabled:sudo ln -s /etc/nginx/sites-available/my-app.com /etc/nginx/sites-enabled/ -
Test Nginx configuration for syntax errors:
sudo nginx -t # Expected output: "test is successful" -
Reload Nginx to apply changes:
sudo systemctl reload nginx -
(Optional) Add
my-app.comto your/etc/hostsfile for local testing:echo "127.0.0.1 my-app.com www.my-app.com" | sudo tee -a /etc/hostsNow, navigate to
http://my-app.comin your browser. You should see “Hello from my-app.com!”.
-
Core Concepts
Understanding these fundamental Nginx concepts is crucial for effective configuration.
| Concept | Description |
|---|---|
| Directive | A configuration instruction, always ending with a semicolon. Can be simple (listen 80;) or block-level (server { ... }). |
| Context | The scope where directives are allowed. Main contexts: main, events, http, “server, location, upstream`. Directives inherit from parent contexts. |
server Block | Defines a virtual host. Nginx decides which server block to use based on listen (IP/port) and server_name (domain name). |
location Block | Defines how Nginx handles requests for different URIs within a server block. Can match prefixes, exact URIs, or regular expressions. Order matters for regex locations. |
upstream Block | Used for load balancing, defining a group of backend servers to which Nginx will proxy requests. |
| Module | Nginx’s functionality is organized into modules (e.g., http_proxy_module, http_ssl_module). Directives belong to specific modules. Most common ones are compiled in by default. |
try_files | A directive used within location blocks to check for the existence of files or directories in a specified order and then serve them or pass the request to another handler. Prevents unnecessary internal redirects. |
proxy_pass | Directs requests to another server (e.g., an application server or an upstream group). Key for reverse proxying. |
Essential Commands / API / Syntax
This section covers the most common Nginx configuration patterns.
Nginx Service Management
# Test configuration syntax without reloading (essential!)
sudo nginx -t
# Reload Nginx to apply new configurations (without dropping connections)
sudo systemctl reload nginx
# Restart Nginx (drops existing connections, use if reload fails or for major changes)
sudo systemctl restart nginx
# Stop Nginx
sudo systemctl stop nginx
# Start Nginx
sudo systemctl start nginx
# Check Nginx status
sudo systemctl status nginx
Basic Server Block (HTTP)
Configuring Nginx to respond to a domain name and serve static files.
# /etc/nginx/sites-available/my-website.com
server {
listen 80; # Listen for HTTP requests
server_name my-website.com www.my-website.com; # Domain names
root /var/www/my-website.com/html; # Document root
index index.html index.htm; # Default files
location / {
try_files $uri $uri/ =404; # Serve file, then directory, or 404
}
access_log /var/log/nginx/my-website.com-access.log;
error_log /var/log/nginx/my-website.com-error.log;
}
HTTPS Configuration (SSL/TLS)
Securing your site with SSL/TLS. Requires obtaining an SSL certificate (e.g., from Let’s Encrypt).
# /etc/nginx/sites-available/my-secure-app.com
server {
listen 80; # Redirect all HTTP traffic to HTTPS
server_name my-secure-app.com www.my-secure-app.com;
return 301 https://$host$request_uri; # Permanent redirect
}
server {
listen 443 ssl http2; # Listen for HTTPS requests
listen [::]:443 ssl http2;
server_name my-secure-app.com www.my-secure-app.com;
# SSL certificate paths (replace with your actual paths)
ssl_certificate /etc/letsencrypt/live/my-secure-app.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/my-secure-app.com/privkey.pem;
# Basic SSL optimizations (Nginx 1.25+)
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM"; # Strong ciphers
ssl_prefer_server_ciphers on;
ssl_stapling on; # OCSP stapling
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s; # Google Public DNS
resolver_timeout 5s;
root /var/www/my-secure-app.com/html;
index index.html;
location / {
try_files $uri $uri/ =404;
}
access_log /var/log/nginx/my-secure-app.com-access.log;
error_log /var/log/nginx/my-secure-app.com-error.log;
}
Reverse Proxying
Directing traffic to an application server (e.g., Node.js, Python, Java).
# /etc/nginx/sites-available/my-api-proxy.com
server {
listen 80;
server_name my-api-proxy.com;
location / {
# Proxy requests to a backend application running on port 3000
proxy_pass http://127.0.0.1:3000;
# Standard proxy headers
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;
# WebSocket proxying (if your backend uses WebSockets)
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
access_log /var/log/nginx/my-api-proxy.com-access.log;
error_log /var/log/nginx/my-api-proxy.com-error.log;
}
Load Balancing
Distributing requests across multiple backend servers using an upstream block.
# Define the group of backend servers
upstream backend_servers {
server 192.168.1.100:8080 weight=5; # Server with higher weight gets more requests
server 192.168.1.101:8080;
server 192.168.1.102:8080;
# Can also use DNS names for servers
# server backend1.example.com;
# Load balancing methods (default is round-robin)
# least_conn; # Send to server with fewest active connections
# ip_hash; # Ensures requests from same client IP go to same server
# fair; # Requires third-party module
# hash $request_uri consistent; # Distribute based on URI hash
}
server {
listen 80;
server_name my-load-balanced-app.com;
location / {
proxy_pass http://backend_servers; # Proxy to the upstream group
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;
}
access_log /var/log/nginx/lb-app-access.log;
error_log /var/log/nginx/lb-app-error.log;
}
Rewrites and Redirects
Changing the URI of a request or sending a client to a different URL.
server {
listen 80;
server_name old-domain.com;
# Permanent redirect for an entire domain
return 301 https://new-domain.com$request_uri;
}
server {
listen 80;
server_name example.com;
location /old-path {
# Internal rewrite (Nginx processes the new URI internally)
rewrite ^/old-path(.*)$ /new-path$1 last;
}
location /legacy-page {
# Permanent redirect for a specific page
return 301 /new-page;
}
location ~ ^/articles/(\d+)/?$ { # Regex location match
# Redirect with capture groups
return 301 /blog/post/$1;
}
# Conditional redirect (use `if` sparingly, `try_files` is usually better)
if ($request_method = POST) {
return 405; # Method Not Allowed
}
}
Access Control & Security
Restricting access based on IP or HTTP Basic Authentication.
server {
listen 80;
server_name restricted.example.com;
# Deny access from specific IPs
deny 192.168.1.1;
allow 192.168.1.0/24; # Allow a subnet
allow all; # Default allow if not denied by rule above
location /admin {
# HTTP Basic Authentication
auth_basic "Restricted Area";
auth_basic_user_file /etc/nginx/.htpasswd; # Path to htpasswd file
# To create .htpasswd:
# sudo apt install apache2-utils # (if not installed)
# sudo htpasswd -c /etc/nginx/.htpasswd admin_user
# (then enter password for admin_user)
proxy_pass http://127.0.0.1:8001;
}
}
Common Patterns
1. Frontend SPA + Backend API Proxy
Serving a Single Page Application (SPA) (e.g., React, Angular, Vue) while proxying API requests to a backend.
# /etc/nginx/sites-available/my-spa-app.com
server {
listen 80;
listen [::]:80;
server_name my-spa-app.com www.my-spa-app.com;
# Assuming your SPA build output is in /var/www/my-spa-app.com/build
root /var/www/my-spa-app.com/build;
index index.html;
# Proxy API requests to your backend on port 5000
location /api/ {
proxy_pass http://localhost:5000;
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;
}
# Serve static assets (e.g., JS, CSS, images) directly
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
expires 30d; # Cache static assets for 30 days
add_header Cache-Control "public, no-transform";
try_files $uri =404;
}
# For any other request, serve the index.html file (SPA routing)
location / {
try_files $uri $uri/ /index.html;
}
access_log /var/log/nginx/my-spa-app.com-access.log;
error_log /var/log/nginx/my-spa-app.com-error.log;
}
2. Rate Limiting
Protecting your application from abuse by limiting the number of requests per client IP.
# In the http block (usually /etc/nginx/nginx.conf or a separate file in /etc/nginx/conf.d/)
http {
# Define a shared memory zone for storing request states (Nginx 1.25+)
# 'mylimit' is the zone name, 10m is 10 megabytes, which can store ~160k states
# rate=10r/s means 10 requests per second.
# burst=20 allows bursts of up to 20 requests over the rate.
# nodelay means Nginx will respond immediately for bursts, otherwise it delays.
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s burst=20 nodelay;
server {
listen 80;
server_name my-rate-limited-app.com;
location / {
# Apply the rate limit to this location
# If the rate is exceeded, Nginx returns a 503 (Service Unavailable)
limit_req zone=mylimit;
proxy_pass http://localhost:3000;
}
# Another location with a stricter limit for sensitive APIs
location /api/login {
limit_req zone=mylimit burst=5 nodelay; # Stricter burst
proxy_pass http://localhost:3000;
}
}
}
Gotchas & Tips
locationBlock Order: The order oflocationblocks matters. Nginx first checks prefix matches, then regex matches. More specific prefix matches take precedence over less specific ones. Regex matches (~or~*) are processed in order of appearance in the configuration file, and the first matching regex location is used. Use^~for a prefix match that, if matched, stops further regex evaluation.try_filesvs.if: Prefertry_filesoverifdirectives whenever possible. Theifdirective can be problematic and lead to unexpected behavior due to its complex processing order within Nginx.try_filesis efficient and designed for checking file existence.reloadvs.restart: Always usesudo systemctl reload nginxto apply configuration changes. This hot-reloads the configuration without dropping active connections. Onlysudo systemctl restart nginxifreloadfails or for very significant changes that require a full service restart (rare).- Test Your Config: Always run
sudo nginx -tbefore reloading or restarting Nginx. This validates your configuration syntax and prevents downtime from typos. - Security Headers (Nginx 1.25+): Add security headers to your
httporserverblocks for better security.# Example security headers add_header X-Frame-Options "SAMEORIGIN"; add_header X-Content-Type-Options "nosniff"; add_header X-XSS-Protection "1; mode=block"; add_header Referrer-Policy "no-referrer-when-downgrade"; add_header Content-Security-Policy "default-src 'self' data: 'unsafe-inline' 'unsafe-eval' https://*;"; # Tailor this carefully - Caching: Nginx can cache responses for static files or proxied content, significantly reducing backend load and improving performance. Look into
proxy_cache_pathandproxy_cachedirectives for advanced caching. - Logging: Configure specific
access_loganderror_logdirectives for eachserverblock to simplify debugging and monitoring. Custom log formats (log_format) provide more granular information.
Next Steps
- Official Nginx Documentation: The ultimate source for comprehensive information on every directive and module. nginx.org/en/docs/
- Let’s Encrypt with Certbot: Easily obtain and manage free SSL certificates for your Nginx servers. certbot.eff.org
- z2h.fyi/cheatsheets/linux-cli: Brush up on your Linux command line skills for easier server management.
Source: z2h.fyi/cheatsheets/nginx-configuration — Zero to Hero cheatsheets for developers.
---
*Source: [z2h.fyi/cheatsheets/nginx-configuration-cheatsheet](https://z2h.fyi/cheatsheets/nginx-configuration-cheatsheet) — Zero to Hero cheatsheets for developers.*