Configure nginx for static sites, reverse proxying, load balancing, SSL/TLS termination, caching, and performance tuning. When setting up web servers, application proxies, or load balancers, this skill provides production-ready patterns with modern security best practices for TLS 1.3, rate limiting, and security headers.
Guide engineers through configuring nginx for common web infrastructure needs: static file serving, reverse proxying backend applications, load balancing across multiple servers, SSL/TLS termination, caching, and performance optimization. Provides production-ready configurations with security best practices.
Use when working with:
Trigger phrases: "configure nginx", "nginx reverse proxy", "nginx load balancer", "enable SSL in nginx", "nginx performance tuning", "nginx caching", "nginx rate limiting"
Ubuntu/Debian:
sudo apt update && sudo apt install nginx -y
sudo systemctl enable nginx
sudo systemctl start nginx
RHEL/CentOS/Rocky:
sudo dnf install nginx -y
sudo systemctl enable nginx
sudo systemctl start nginx
Docker:
docker run -d -p 80:80 -v /path/to/config:/etc/nginx/conf.d nginx:alpine
Serve HTML/CSS/JS files from a directory:
server {
listen 80;
server_name example.com www.example.com;
root /var/www/example.com/html;
index index.html;
location / {
try_files $uri $uri/ =404;
}
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff2)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
}
Enable site:
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
See references/static-sites.md for SPA configurations and advanced patterns.
Proxy requests to a backend application server:
upstream app_backend {
server 127.0.0.1:3000;
keepalive 32;
}
server {
listen 80;
server_name app.example.com;
location / {
proxy_pass http://app_backend;
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_http_version 1.1;
proxy_set_header Connection "";
}
}
See references/reverse-proxy.md for WebSocket proxying and API gateway patterns.
Enable HTTPS with modern TLS configuration:
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;
ssl_protocols TLSv1.3 TLSv1.2;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:50m;
ssl_session_timeout 1d;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
location / {
try_files $uri $uri/ =404;
}
}
server {
listen 80;
server_name example.com;
return 301 https://$server_name$request_uri;
}
See references/ssl-tls-config.md for complete TLS configuration and certificate setup.
nginx uses hierarchical configuration contexts:
nginx.conf (global settings)
├── events { } (connection processing)
└── http { } (HTTP-level settings)
└── server { } (virtual host)
└── location { } (URL routing)
File locations:
/etc/nginx/nginx.conf - Main configuration/etc/nginx/sites-available/ - Available site configs/etc/nginx/sites-enabled/ - Enabled sites (symlinks)/etc/nginx/conf.d/*.conf - Additional configs/etc/nginx/snippets/ - Reusable config snippetsSee references/configuration-structure.md for detailed anatomy.
nginx evaluates location blocks in this order:
location = /exact - Exact match (highest priority)location ^~ /prefix - Prefix match, stop searchinglocation ~ \.php$ - Regex, case-sensitivelocation ~* \.(jpg|png)$ - Regex, case-insensitivelocation / - Prefix match (lowest priority)Example:
location = /api/status {
return 200 "OK\n";
}
location ^~ /static/ {
root /var/www;
}
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php-fpm.sock;
}
location / {
proxy_pass http://backend;
}
When proxying to backends, preserve 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;
Create reusable snippet at /etc/nginx/snippets/proxy-params.conf and include with:
include snippets/proxy-params.conf;
Distribute traffic across multiple backend servers:
Round Robin (default):
upstream backend {
server backend1.example.com:8080;
server backend2.example.com:8080;
server backend3.example.com:8080;
keepalive 32;
}
server {
listen 80;
location / {
proxy_pass http://backend;
include snippets/proxy-params.conf;
}
}
Least Connections:
upstream backend {
least_conn;
server backend1.example.com:8080;
server backend2.example.com:8080;
}
IP Hash (sticky sessions):
upstream backend {
ip_hash;
server backend1.example.com:8080;
server backend2.example.com:8080;
}
Health Checks:
upstream backend {
server backend1.example.com:8080 max_fails=3 fail_timeout=30s;
server backend2.example.com:8080 max_fails=3 fail_timeout=30s;
server backup.example.com:8080 backup;
}
See references/load-balancing.md for weighted load balancing and advanced patterns.
Enable WebSocket connections by upgrading HTTP protocol:
upstream websocket_backend {
server 127.0.0.1:3000;
}
server {
listen 80;
server_name ws.example.com;
location / {
proxy_pass http://websocket_backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
# Long timeouts for persistent connections
proxy_connect_timeout 7d;
proxy_send_timeout 7d;
proxy_read_timeout 7d;
}
}
Protect against abuse and DDoS attacks:
# In http context
http {
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=5r/s;
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
}
# In server context
server {
listen 80;
limit_req zone=api_limit burst=10 nodelay;
limit_conn conn_limit 10;
location /api/ {
proxy_pass http://backend;
}
}
See references/security-hardening.md for complete security configuration.
Worker Configuration:
# In main context
user www-data;
worker_processes auto; # 1 per CPU core
worker_rlimit_nofile 65535;
events {
worker_connections 4096;
use epoll;
multi_accept on;
}
Gzip Compression:
# In http context
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_comp_level 6;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml;
Proxy Caching:
# Define cache zone
proxy_cache_path /var/cache/nginx/proxy
levels=1:2
keys_zone=app_cache:100m
max_size=1g
inactive=60m;
# Use in location
location / {
proxy_cache app_cache;
proxy_cache_valid 200 60m;
proxy_cache_use_stale error timeout updating;
add_header X-Cache-Status $upstream_cache_status;
proxy_pass http://backend;
}
See references/performance-tuning.md for detailed optimization strategies.
Add essential security headers to protect against common vulnerabilities:
# Create /etc/nginx/snippets/security-headers.conf
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline';" always;
Include in server blocks:
server {
include snippets/security-headers.conf;
# ... rest of config
}
Restrict access by IP address:
server {
listen 80;
server_name admin.example.com;
# Allow specific IPs
allow 10.0.0.0/8;
allow 203.0.113.0/24;
# Deny all others
deny all;
location / {
proxy_pass http://admin_backend;
}
}
Choose nginx for: Performance-critical workloads (10K+ connections), reverse proxy, load balancing, static file serving, modern application stacks.
Choose alternatives for: Apache (.htaccess, mod_php, legacy apps), Caddy (auto-HTTPS, simpler config), Traefik (dynamic containers), Envoy (service mesh).
Before deploying nginx configurations:
sudo nginx -tsudo systemctl reload nginx (zero downtime)sudo tail -f /var/log/nginx/error.logopenssl s_client -connect domain:443 -servername domaincurl -I https://domain.comps aux | grep nginxnetstat -an | grep :80 | wc -lcurl -I http://localhost:8080Quick fixes: Test config (sudo nginx -t), check logs (/var/log/nginx/error.log), verify backend (curl http://127.0.0.1:3000).
Common errors: 502 (backend down), 504 (timeout - increase proxy_read_timeout), 413 (upload size - set client_max_body_size).
See references/troubleshooting.md for complete debugging guide.
Related Skills:
Progressive Disclosure:
references/installation-guide.md - Detailed installation for all platformsreferences/configuration-structure.md - Complete nginx.conf anatomyreferences/static-sites.md - Static hosting patterns (basic, SPA, PHP)references/reverse-proxy.md - Advanced proxy scenarios and API gateway patternsreferences/load-balancing.md - All algorithms, health checks, sticky sessionsreferences/ssl-tls-config.md - Complete TLS configuration and certificate setupreferences/performance-tuning.md - Workers, caching, compression, buffersreferences/security-hardening.md - Rate limiting, headers, access controlreferences/troubleshooting.md - Common errors and debugging techniquesWorking Examples:
examples/static-site/ - Static website and SPA configurationsexamples/reverse-proxy/ - Node.js, WebSocket, API gateway examplesexamples/load-balancing/ - All load balancing algorithmsexamples/ssl-tls/ - Modern TLS and mTLS configurationsexamples/performance/ - High-traffic optimization and cachingexamples/security/ - Rate limiting and security hardeningReusable Snippets:
snippets/ssl-modern.conf - Modern TLS configurationsnippets/proxy-params.conf - Standard proxy headerssnippets/security-headers.conf - OWASP security headerssnippets/cache-static.conf - Static asset cachingSearch for places (restaurants, cafes, etc.) via Google Places API proxy on localhost.
Interact with GitHub using the `gh` CLI. Use `gh issue`, `gh pr`, `gh run`, and `gh api` for issues, PRs, CI runs, and advanced queries.
Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Start voice calls via the OpenClaw voice-call plugin.
Notion API for creating and managing pages, databases, and blocks.
Gemini CLI for one-shot Q&A, summaries, and generation.
Category:developer