← Back to all cheatsheets
DevOps
nginxweb-serverdevopsreverse-proxyload-balancing

Nginx DevOps Cheat Sheet

Essential Commands

Service Management

# Start/Stop/Restart
systemctl start nginx
systemctl stop nginx
systemctl restart nginx
systemctl reload nginx    # Graceful reload without dropping connections

# Status & Enable
systemctl status nginx
systemctl enable nginx    # Enable on boot
systemctl disable nginx

# Alternative commands (older systems)
service nginx start/stop/restart/reload
/etc/init.d/nginx start/stop/restart/reload

Configuration Testing & Reload

nginx -t                  # Test configuration syntax
nginx -T                  # Test and dump full configuration
nginx -s reload          # Reload configuration
nginx -s quit            # Graceful shutdown
nginx -s stop            # Fast shutdown
nginx -s reopen          # Reopen log files

Process Management

ps aux | grep nginx      # View nginx processes
nginx -V                 # Version and compile options
nginx -v                 # Version only
lsof -i :80             # Check what's using port 80
netstat -tlpn | grep :80

File Locations

Default Paths

/etc/nginx/                     # Main configuration directory
/etc/nginx/nginx.conf          # Main configuration file
/etc/nginx/sites-available/    # Available site configurations (Debian/Ubuntu)
/etc/nginx/sites-enabled/      # Enabled site configurations (symlinks)
/etc/nginx/conf.d/             # Additional configuration files (RHEL/CentOS)
/var/log/nginx/                # Log files
/var/www/html/                 # Default web root
/usr/share/nginx/html/         # Alternative default web root

Core Configuration Directives

Main Context (nginx.conf)

user www-data;                           # Worker process user
worker_processes auto;                   # Number of worker processes
worker_connections 1024;                 # Max connections per worker
pid /var/run/nginx.pid;

events {
    worker_connections 1024;
    use epoll;                          # Connection processing method
    multi_accept on;
}

http {
    # Basic Settings
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;
    server_tokens off;                  # Hide nginx version

    # Buffer Settings
    client_body_buffer_size 16K;
    client_header_buffer_size 1k;
    large_client_header_buffers 4 16k;
    client_max_body_size 100M;          # Max upload size

    # Logging
    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log warn;

    # Gzip Compression
    gzip on;
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_types text/plain text/css text/xml text/javascript
               application/json application/javascript application/xml+rss;
}

Server Block Examples

Basic HTTP Server

server {
    listen 80;
    server_name example.com www.example.com;
    root /var/www/example.com;
    index index.html index.htm;

    location / {
        try_files $uri $uri/ =404;
    }
}

HTTPS with SSL/TLS

server {
    listen 443 ssl http2;
    server_name example.com;

    ssl_certificate /etc/ssl/certs/example.com.crt;
    ssl_certificate_key /etc/ssl/private/example.com.key;

    # Modern SSL configuration
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;

    # Security headers
    add_header Strict-Transport-Security "max-age=31536000" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
}

HTTP to HTTPS Redirect

server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://$server_name$request_uri;
}

Reverse Proxy Configuration

Basic Reverse Proxy

location / {
    proxy_pass http://localhost:3000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
    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_cache_bypass $http_upgrade;
}

Load Balancing

upstream backend {
    least_conn;  # or ip_hash, random, etc.
    server backend1.example.com weight=3;
    server backend2.example.com;
    server backend3.example.com down;
    server backend4.example.com backup;
}

server {
    location / {
        proxy_pass http://backend;
    }
}

Location Block Patterns

Priority Order (High to Low)

location = /exact { }              # Exact match
location ^~ /prefix { }            # Prefix match (stops search)
location ~ /regex[0-9] { }         # Case-sensitive regex
location ~* /regex[0-9] { }        # Case-insensitive regex
location /prefix { }               # Prefix match
location / { }                     # Default

Common Location Examples

# Static files with caching
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
    expires 30d;
    add_header Cache-Control "public, immutable";
}

# PHP-FPM
location ~ \.php$ {
    fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include fastcgi_params;
}

# Deny access to hidden files
location ~ /\. {
    deny all;
}

# WebSocket support
location /ws/ {
    proxy_pass http://localhost:3000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
}

Rate Limiting & Security

Rate Limiting

http {
    limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
    limit_conn_zone $binary_remote_addr zone=addr:10m;

    server {
        location /api/ {
            limit_req zone=one burst=5 nodelay;
            limit_conn addr 10;
        }
    }
}

Basic Authentication

location /admin {
    auth_basic "Admin Area";
    auth_basic_user_file /etc/nginx/.htpasswd;
}

IP Whitelisting/Blacklisting

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

Caching

Proxy Cache

http {
    proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m
                     max_size=10g inactive=60m use_temp_path=off;

    server {
        location / {
            proxy_cache my_cache;
            proxy_cache_valid 200 302 60m;
            proxy_cache_valid 404 1m;
            proxy_cache_use_stale error timeout invalid_header updating;
            add_header X-Cache-Status $upstream_cache_status;
        }
    }
}

Useful Variables

$host              # Host header value
$remote_addr       # Client IP address
$request_method    # GET, POST, etc.
$request_uri       # Full original request URI
$uri               # Current URI
$args              # Query string
$scheme            # http or https
$server_name       # Server name
$server_port       # Server port
$http_user_agent   # User agent string
$http_referer      # Referrer
$upstream_addr     # Upstream server address
$upstream_response_time  # Upstream response time
$request_time      # Total request processing time

Logging

Custom Log Format

http {
    log_format custom '$remote_addr - $remote_user [$time_local] '
                      '"$request" $status $body_bytes_sent '
                      '"$http_referer" "$http_user_agent" '
                      'rt=$request_time uct="$upstream_connect_time" '
                      'uht="$upstream_header_time" urt="$upstream_response_time"';

    access_log /var/log/nginx/access.log custom;
}

Conditional Logging

map $request_uri $loggable {
    ~*\.(jpg|jpeg|png|gif|ico|css|js)$ 0;
    default 1;
}

access_log /var/log/nginx/access.log combined if=$loggable;

Performance Tuning

Key Optimizations

# File descriptors
worker_rlimit_nofile 65535;

# Events block
events {
    worker_connections 4096;
    use epoll;
    multi_accept on;
}

http {
    # Connection settings
    keepalive_timeout 65;
    keepalive_requests 100;

    # Buffer optimizations
    client_body_buffer_size 128k;
    large_client_header_buffers 4 16k;

    # File cache
    open_file_cache max=1000 inactive=20s;
    open_file_cache_valid 30s;
    open_file_cache_min_uses 2;
    open_file_cache_errors on;

    # Gzip
    gzip on;
    gzip_comp_level 5;
    gzip_min_length 256;
    gzip_proxied any;
    gzip_vary on;
}

Troubleshooting Commands

# Check syntax errors
nginx -t

# View error logs
tail -f /var/log/nginx/error.log

# View access logs
tail -f /var/log/nginx/access.log

# Test specific configuration file
nginx -t -c /etc/nginx/nginx.conf

# Check listening ports
ss -tlnp | grep nginx
netstat -tlnp | grep nginx

# Check nginx processes
ps aux | grep nginx

# Test upstream connectivity
curl -I http://backend-server:port

# Check disk space for logs
df -h /var/log

# Rotate logs manually
nginx -s reopen

# Check current connections
ss -ant | grep :80 | wc -l

# Monitor nginx status (requires stub_status module)
curl http://localhost/nginx_status

Docker/Kubernetes Integration

Docker Example

FROM nginx:alpine
COPY nginx.conf /etc/nginx/nginx.conf
COPY site.conf /etc/nginx/conf.d/default.conf
EXPOSE 80 443

Kubernetes ConfigMap

apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-config
data:
  nginx.conf: |
    events { }
    http {
      server {
        listen 80;
        location / {
          proxy_pass http://backend-service:3000;
        }
      }
    }

Common Issues & Solutions

IssueSolution
502 Bad GatewayCheck upstream server status, firewall rules, SELinux
504 Gateway TimeoutIncrease proxy_read_timeout, check upstream response time
413 Request Entity Too LargeIncrease client_max_body_size
Too many open filesIncrease worker_rlimit_nofile and system limits
Permission deniedCheck file ownership, SELinux contexts
Address already in useCheck for other processes on port (lsof -i :80)

Quick Tips

  • Always test configuration before reload: nginx -t
  • Use nginx -T to view the full resolved configuration
  • Enable gzip compression for text-based content
  • Set up proper logging and log rotation
  • Use try_files directive instead of if when possible
  • Implement rate limiting for API endpoints
  • Keep Nginx and modules updated
  • Monitor access and error logs regularly
  • Use configuration management tools for consistency across servers