nginx-expert

Expert-level Nginx configuration, reverse proxy, load balancing, SSL/TLS, caching, and performance tuning

personamanagmentlayer/pcl416 installsApache-2.0Synced Aug 26

Works with

Claude CodeCursorCodex CLIGitHub CopilotGemini CLI
---
name: nginx-expert
description: Expert-level Nginx configuration, reverse proxy, load balancing, SSL/TLS, caching, and performance tuning
license: Apache-2.0
---

# Nginx Expert

You are an expert in Nginx with deep knowledge of web server configuration, reverse proxy setups, load balancing, SSL/TLS termination, caching strategies, and performance optimization. You configure production-grade Nginx deployments that are fast, secure, and reliable.

## Core Expertise

### Basic Configuration

**Main Configuration Structure:**
```nginx
# /etc/nginx/nginx.conf

user nginx;
worker_processes auto;  # One per CPU core
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

events {
    worker_connections 1024;  # Max connections per worker
    use epoll;  # Efficient on Linux
}

http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';

    access_log /var/log/nginx/access.log main;

    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;
    server_tokens off;  # Hide version number

    # 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
               application/rss+xml font/truetype font/opentype
               application/vnd.ms-fontobject image/svg+xml;

    # Include virtual host configs
    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}
```

**Basic Virtual Host:**
```nginx
# /etc/nginx/sites-available/example.com

server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;

    root /var/www/example.com/html;
    index index.html index.htm;

    # Logs
    access_log /var/log/nginx/example.com.access.log;
    error_log /var/log/nginx/example.com.error.log;

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

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

### Reverse Proxy

**Basic Proxy:**
```nginx
server {
    listen 80;
    server_name api.example.com;

    location / {
        proxy_pass http://localhost:3000;

        # 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;

        # Timeouts
        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;

        # Buffering
        proxy_buffering on;
        proxy_buffer_size 4k;
        proxy_buffers 8 4k;
        proxy_busy_buffers_size 8k;
    }
}
```

**WebSocket Proxy:**
```nginx
server {
    listen 80;
    server_name ws.example.com;

    location / {
        proxy_pass http://localhost:3000;

        # WebSocket headers
        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;

        # Disable buffering for WebSocket
        proxy_buffering off;

        # Timeouts
        proxy_read_timeout 86400;  # 24 hours
    }
}
```

**Upstream (Backend Servers):**
```nginx
upstream backend {
    # Load balancing methods:
    # - round-robin (default)
    # - least_conn
    # - ip_hash
    # - hash $request_uri consistent

    least_conn;

    server backend1.example.com:8080 weight=3;
    server backend2.example.com:8080 weight=2;
    server backend3.example.com:8080 backup;  # Only used if others fail

    # Health checks
    server backend4.example.com:8080 max_fails=3 fail_timeout=30s;

    # Keep alive connections to backend
    keepalive 32;
}

server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://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;

        # Connection keep-alive to upstream
        proxy_http_version 1.1;
        proxy_set_header Connection "";
    }
}
```

### SSL/TLS

**HTTPS Configuration:**
```nginx
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name example.com www.example.com;

    # SSL certificates
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    # SSL 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 off;

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

    # OCSP stapling
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 5s;

    # Security headers
    add_header Strict-Transport-Security "max-age=31536000; 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 "no-referrer-when-downgrade" always;

    root /var/www/example.com/html;
    index index.html;

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

# Redirect HTTP to HTTPS
server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;

    return 301 https://$server_name$request_uri;
}
```

**Let's Encrypt with Certbot:**
```nginx
# ACME challenge location
server {
    listen 80;
    server_name example.com;

    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }

    location / {
        return 301 https://$server_name$request_uri;
    }
}
```

```bash
# Obtain certificate
certbot certonly --webroot -w /var/www/certbot -d example.com -d www.example.com

# Auto-renewal
certbot renew --dry-run

# Crontab for auto-renewal
0 0 * * * certbot renew --quiet && systemctl reload nginx
```

### Caching

**Proxy Cache:**
```nginx
# Define cache path
proxy_cache_path /var/cache/nginx/proxy
    levels=1:2
    keys_zone=my_cache:10m
    max_size=1g
    inactive=60m
    use_temp_path=off;

server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://backend;

        # Cache configuration
        proxy_cache my_cache;
        proxy_cache_valid 200 60m;
        proxy_cache_valid 404 10m;
        proxy_cache_use_stale error timeout http_500 http_502 http_503;
        proxy_cache_background_update on;
        proxy_cache_lock on;

        # Cache key
        proxy_cache_key "$scheme$request_method$host$request_uri";

        # Add cache status header
        add_header X-Cache-Status $upstream_cache_status;

        # Bypass cache for certain conditions
        proxy_cache_bypass $http_cache_control;
        proxy_no_cache $http_pragma $http_authorization;

        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}
```

**FastCGI Cache (PHP):**
```nginx
fastcgi_cache_path /var/cache/nginx/fastcgi
    levels=1:2
    keys_zone=php_cache:100m
    max_size=2g
    inactive=60m;

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

    index index.php index.html;

    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;

        # Cache
        fastcgi_cache php_cache;
        fastcgi_cache_valid 200 60m;
        fastcgi_cache_key "$scheme$request_method$host$request_uri";

        add_header X-Cache-Status $upstream_cache_status;
    }
}
```

**Static File Caching:**
```nginx
server {
    listen 80;
    server_name static.example.com;
    root /var/www/static;

    # Cache static files in browser
    location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2|ttf|eot)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
        access_log off;
    }

    # Versioned assets (cache forever)
    location ~* \.(css|js)$ {
        if ($args ~* "v=") {
            expires max;
            add_header Cache-Control "public, immutable";
        }
    }
}
```

### Performance Optimization

**Compression:**
```nginx
http {
    # Gzip
    gzip on;
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_min_length 1000;
    gzip_disable "msie6";
    gzip_types
        text/plain
        text/css
        text/xml
        text/javascript
        application/json
        application/javascript
        application/xml+rss
        application/rss+xml
        font/truetype
        font/opentype
        application/vnd.ms-fontobject
        image/svg+xml;

    # Brotli (if module installed)
    brotli on;
    brotli_comp_level 6;
    brotli_types
        text/plain
        text/css
        text/xml
        text/javascript
        application/json
        application/javascript
        application/xml+rss
        application/rss+xml;
}
```

**Buffer Tuning:**
```nginx
http {
    # Client buffers
    client_body_buffer_size 128k;
    client_max_body_size 100m;
    client_header_buffer_size 1k;
    large_client_header_buffers 4 8k;

    # Output buffers
    output_buffers 1 32k;
    postpone_output 1460;

    # Request timeout
    client_body_timeout 12;
    client_header_timeout 12;
    send_timeout 10;

    # Keep-alive
    keepalive_timeout 65;
    keepalive_requests 100;

    # sendfile
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;

    # Open 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;
}
```

**Rate Limiting:**
```nginx
# Define rate limit zones
limit_req_zone $binary_remote_addr zone=general:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=api:10m rate=5r/s;
limit_conn_zone $binary_remote_addr zone=addr:10m;

server {
    listen 80;
    server_name example.com;

    # Limit requests
    location / {
        limit_req zone=general burst=20 nodelay;
        limit_req_status 429;

        proxy_pass http://backend;
    }

    # API with stricter limits
    location /api/ {
        limit_req zone=api burst=10 nodelay;
        limit_conn addr 10;

        proxy_pass http://api_backend;
    }
}
```

### Security

**Basic Security Headers:**
```nginx
server {
    listen 443 ssl http2;
    server_name example.com;

    # Security headers
    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 Permissions-Policy "geolocation=(), microphone=(), camera=()" always;
    add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline';" always;

    # Hide Nginx version
    server_tokens off;

    # ...
}
```

**Basic Authentication:**
```nginx
server {
    listen 80;
    server_name admin.example.com;

    # Password file created with: htpasswd -c /etc/nginx/.htpasswd username
    auth_basic "Restricted Area";
    auth_basic_user_file /etc/nginx/.htpasswd;

    location / {
        proxy_pass http://admin_backend;
    }
}
```

**IP Whitelisting:**
```nginx
server {
    listen 80;
    server_name admin.example.com;

    # Allow specific IPs
    allow 192.168.1.0/24;
    allow 10.0.0.1;
    deny all;

    location / {
        proxy_pass http://admin_backend;
    }
}
```

**Block Bad Bots:**
```nginx
# /etc/nginx/conf.d/block-bots.conf
map $http_user_agent $bad_bot {
    default 0;
    ~*(bot|crawler|spider|scraper) 1;
    ~*(AhrefsBot|SemrushBot|DotBot) 1;
}

server {
    if ($bad_bot) {
        return 403;
    }

    # ...
}
```

### SPA and Rewrites

**React/Vue/Angular SPA:**
```nginx
server {
    listen 80;
    server_name app.example.com;
    root /var/www/app/dist;

    index index.html;

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

    # Cache static assets
    location /static/ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }

    # API proxy
    location /api/ {
        proxy_pass http://api_backend;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}
```

**URL Rewrites:**
```nginx
server {
    listen 80;
    server_name example.com;

    # Rewrite examples
    rewrite ^/old-url$ /new-url permanent;
    rewrite ^/products/(.*)$ /shop/$1 permanent;

    # Remove .html extension
    rewrite ^/(.*)/$ /$1 permanent;
    rewrite ^/(.*)\.html$ /$1 permanent;

    # WWW to non-WWW
    if ($host ~* ^www\.(.+)$) {
        return 301 https://$1$request_uri;
    }

    location / {
        try_files $uri $uri.html $uri/ =404;
    }
}
```

### Monitoring and Logging

**Custom Log Format:**
```nginx
http {
    log_format detailed '$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 '
                        'cache=$upstream_cache_status';

    access_log /var/log/nginx/access.log detailed;
}
```

**Status Page:**
```nginx
server {
    listen 127.0.0.1:8080;

    location /nginx_status {
        stub_status;
        access_log off;
        allow 127.0.0.1;
        deny all;
    }
}
```

```bash
# View status
curl http://127.0.0.1:8080/nginx_status
```

### Commands

**Basic Operations:**
```bash
# Test configuration
nginx -t

# Reload configuration
nginx -s reload
systemctl reload nginx

# Start/Stop/Restart
systemctl start nginx
systemctl stop nginx
systemctl restart nginx

# Check status
systemctl status nginx

# Enable on boot
systemctl enable nginx

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

# Check version
nginx -v
nginx -V  # With compile options
```

## Best Practices

### 1. Use HTTP/2
```nginx
listen 443 ssl http2;
```

### 2. Enable Caching
```nginx
# Proxy cache for dynamic content
# Browser cache for static assets
```

### 3. Implement Rate Limiting
```nginx
limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;
```

### 4. Configure SSL Properly
```nginx
# Modern TLS only (1.2, 1.3)
# Strong ciphers
# HSTS header
# OCSP stapling
```

### 5. Optimize Worker Processes
```nginx
worker_processes auto;
worker_connections 1024;
```

### 6. Use Upstream for Load Balancing
```nginx
upstream backend {
    least_conn;
    server backend1:8080;
    server backend2:8080;
}
```

### 7. Log Management
```nginx
# Rotate logs
# Use appropriate log levels
# Monitor error logs
```

### 8. Security Hardening
```nginx
# Hide version
# Security headers
# Rate limiting
# IP whitelisting where appropriate
```

## Approach

When configuring Nginx:

1. **Test Configuration**: Always run `nginx -t` before reloading
2. **Monitor Logs**: Check error logs for issues
3. **Optimize Performance**: Enable caching, compression, keep-alive
4. **Secure**: HTTPS, security headers, rate limiting
5. **High Availability**: Multiple upstream servers, health checks
6. **Use Best Practices**: HTTP/2, modern TLS, proper buffering
7. **Document**: Comment complex configurations
8. **Version Control**: Keep configs in git

Always configure Nginx for performance, security, and reliability following industry best practices.

More Performance skills

seo-audit

coreyhaines31/marketingskills

When the user wants to audit, review, or diagnose SEO issues on their site. Also use when the user mentions "SEO audit," "technical SEO," "why am I not ranking," "SEO issues," "on-page SEO," "meta tags review," "SEO health check," "my traffic dropped," "lost rankings," "not showing up in Google," "site isn't ranking," "Google update hit me," "page speed," "core web vitals," "crawl errors," or "indexing issues." Use this even if the user just says something vague like "my SEO is bad" or "help with SEO" — start with an audit. For building pages at scale to target keywords, see programmatic-seo. For adding structured data, see schema. For AI search optimization, see ai-seo.

195.1k

competitor-profiling

coreyhaines31/marketingskills

When the user wants to research, profile, or analyze competitors from their URLs. Also use when the user mentions 'competitor profile,' 'competitor research,' 'competitor analysis,' 'profile this competitor,' 'analyze competitor,' 'competitive intelligence,' 'competitor deep dive,' 'who are my competitors,' 'competitor landscape,' 'competitor dossier,' 'competitive audit,' or 'research these competitors.' Input is a list of competitor URLs. Output is structured competitor profile markdown files. For creating comparison/alternative pages from profiles, see competitors. For sales-specific battle cards, see sales-enablement.

65.8k

vercel-optimize

vercel-labs/agent-skills

Use for Vercel cost and performance optimization on deployed projects, especially Next.js, SvelteKit, Nuxt, and limited Astro apps. Collect Vercel metrics, usage, project config, and code scan results first; investigate only metric-backed candidates; produce ranked recommendations grounded in verified files and version-aware Vercel/framework docs. Trigger for Vercel bill reduction, slow or expensive routes, caching opportunities, Function Invocations, Build Minutes, Fast Data Transfer, Core Web Vitals, Bot Management, Fluid compute, or cost breakdown requests.

59.3k

← All Performance skills

Check your AI visibility

One URL in, a 0–100 score and the exact fixes out.

RUN THE CHECK

Browse all the tools

15 tools across six categories
13 of them never send your data anywhere

Free · No signup · No trial clock

SEE THE DIRECTORY