agentleFS
AlteriomAlteriom/ai-dev-skills/skills/nginx/SKILL.md

nginx

Skill0 starsChanged 3 months agoMITView on GitHub

Configure Nginx for reverse proxy, load balancing, SSL/TLS termination, caching, and high-performance static file serving

  • Installs packages

10 other projects use a version of this, 3 of them edited.

Adopted by

Most recently taken up by

The file

We split this skill into the rules it gives an agent

8 rules. 0 are common, 5 are distinctive, and 3 are very specific to this project.

  • 0

    Common

    Most of the 9 edited versions we read keep these.

  • 5

    Distinctive

    This author's own choices. Worth a look.

  • 3

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Use this skill when:

    line 24
  2. Distinctive:

    Don't use: when you need:

    line 34
  3. Distinctive:

    Karpathy Principle: Simplicity First: - Start with a single server block.

    line 83
  4. Very specific:

    Karpathy Principle: Goal-Driven Execution: - After SSL setup, test with curl -vI https://app.example.com.

    line 168
  5. Very specific:

    Karpathy Principle: Security By Design: - Default configs expose server version (Server: nginx/1.24.0) and allow directory listing.

    line 170
  6. Very specific:

    Karpathy Principle: When NOT to Use: - Don't use nginx proxy_cache for user-specific data (sessions, auth tokens).

    line 172
  7. Distinctive:

    Before deploying Nginx configurations:

    line 421
  8. Distinctive:

    Never expose databases directly

    line 468

“Common” is measured: kept by at least 6 in 10 of the 9 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Nginx - High-Performance Web Server

When to Use

Use this skill when:

  • Reverse proxying applications (Node.js, Python, Go services)
  • Serving static files (React, Next.js builds, images, videos)
  • Load balancing across multiple backend servers
  • SSL/TLS termination for HTTPS
  • Caching API responses or static content
  • Rate limiting and DDoS protection
  • Setting up CDN edge servers

Don't use when you need:

  • Application server capabilities (use Node.js, Python, etc.)
  • Complex business logic in web server
  • Windows-specific features (IIS is better)
  • Built-in WebSocket support (use nginx-extras or alternatives)

Karpathy Principle: Think Before Coding - Nginx configuration is declarative, not imperative. Plan your location blocks hierarchy before writing. Test every change with nginx -t before reloading.

Karpathy Principle: Trade-offs Everywhere - Nginx trades simplicity (vs Apache's .htaccess) for performance. You get 10x throughput but lose runtime config changes. Choose Nginx when performance > flexibility.

Prerequisites

Required Knowledge

  • HTTP basics (methods, headers, status codes)
  • DNS and domain configuration
  • SSL/TLS concepts (certificates, keys, CA)
  • Linux file permissions and systemd

Required Tools

# Install Nginx (Ubuntu/Debian)
sudo apt update
sudo apt install nginx

# Install Nginx (CentOS/RHEL)
sudo yum install nginx

# Verify installation
nginx -v
nginx -t  # Test configuration

# Control Nginx
sudo systemctl start nginx
sudo systemctl enable nginx
sudo systemctl status nginx

Configuration Structure

/etc/nginx/
├── nginx.conf              # Main config
├── sites-available/        # Virtual host configs
│   └── example.com
├── sites-enabled/          # Symlinks to active sites
│   └── example.com -> ../sites-available/example.com
├── conf.d/                 # Additional configs
└── ssl/                    # SSL certificates

Karpathy Principle: Simplicity First - Start with a single server block. Add complexity (upstreams, caching, rate limiting) only when needed. Each feature adds configuration complexity and potential failure points.

Karpathy Principle: Fail Fast, Fail Loud - Enable error_log /var/log/nginx/error.log warn; in development. Silent failures in production are how security holes happen. Monitor 4xx/5xx rates.

Core Workflows

1. Reverse Proxy Setup

Basic Reverse Proxy:

# /etc/nginx/sites-available/app.example.com
server {
    listen 80;
    server_name app.example.com;

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

Enable site:

sudo ln -s /etc/nginx/sites-available/app.example.com /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

2. SSL/TLS Configuration

Let's Encrypt with Certbot:

# Install Certbot
sudo apt install certbot python3-certbot-nginx

# Get certificate (automatic Nginx config)
sudo certbot --nginx -d app.example.com

# Auto-renew
sudo systemctl enable certbot.timer

Manual SSL Configuration:

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

    # SSL Certificate
    ssl_certificate /etc/nginx/ssl/app.example.com.crt;
    ssl_certificate_key /etc/nginx/ssl/app.example.com.key;

    # SSL Settings (Mozilla Intermediate)
    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;

    # HSTS (optional but recommended)
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

    location / {
        proxy_pass http://localhost:3000;
        # ... (proxy headers as above)
    }
}

# HTTP to HTTPS redirect
server {
    listen 80;
    server_name app.example.com;
    return 301 https://$server_name$request_uri;
}

Karpathy Principle: Goal-Driven Execution - After SSL setup, test with curl -vI https://app.example.com. Verify certificate chain, HSTS header, and redirect. Use SSL Labs to verify security grade.

Karpathy Principle: Security By Design - Default configs expose server version (Server: nginx/1.24.0) and allow directory listing. Harden with server_tokens off; and autoindex off;. Attackers scan for version-specific CVEs.

Karpathy Principle: When NOT to Use - Don't use nginx proxy_cache for user-specific data (sessions, auth tokens). Only cache public, identical-for-all-users responses. Otherwise you leak data.

3. Static File Serving

Next.js / React Build:

server {
    listen 80;
    server_name app.example.com;
    root /var/www/app/dist;  # or /var/www/app/.next/static

    # Gzip compression
    gzip on;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
    gzip_min_length 1000;

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

    # SPA fallback (client-side routing)
    location / {
        try_files $uri $uri/ /index.html;
    }
}

4. Load Balancing

Multiple Backend Servers:

upstream backend {
    # Load balancing method (default: round-robin)
    least_conn;  # or ip_hash for sticky sessions

    server 10.0.1.10:3000 weight=3;  # More traffic to this server
    server 10.0.1.11:3000;
    server 10.0.1.12:3000 backup;    # Only if others fail

    # Health checks
    server 10.0.1.13:3000 max_fails=3 fail_timeout=30s;

    # Connection pooling
    keepalive 32;
}

server {
    listen 80;
    server_name api.example.com;

    location / {
        proxy_pass http://backend;
        proxy_http_version 1.1;
        proxy_set_header Connection "";  # Keep-alive to upstream
        # ... (proxy headers)
    }
}

Common Patterns

1. API + Static SPA

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

    root /var/www/app/dist;

    # API routes
    location /api {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        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;
    }

    # Static assets
    location / {
        try_files $uri $uri/ /index.html;
    }
}

2. Rate Limiting

# Define rate limit zone (10MB zone, 10 requests/second per IP)
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;

server {
    location /api {
        limit_req zone=api_limit burst=20 nodelay;
        limit_req_status 429;
        
        proxy_pass http://backend;
    }
}

3. Caching

# Cache path and keys
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=api_cache:10m max_size=1g inactive=60m use_temp_path=off;

server {
    location /api {
        proxy_cache api_cache;
        proxy_cache_key "$scheme$request_method$host$request_uri";
        proxy_cache_valid 200 10m;
        proxy_cache_valid 404 1m;
        proxy_cache_bypass $http_cache_control;
        add_header X-Cache-Status $upstream_cache_status;
        
        proxy_pass http://backend;
    }
}

4. Multiple Domains

# app.example.com
server {
    listen 443 ssl http2;
    server_name app.example.com;
    # ... (app config)
}

# api.example.com
server {
    listen 443 ssl http2;
    server_name api.example.com;
    # ... (api config)
}

# www.example.com → example.com redirect
server {
    listen 443 ssl http2;
    server_name www.example.com;
    return 301 https://example.com$request_uri;
}

5. WebSocket Proxy

map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;
}

server {
    location /ws {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_set_header Host $host;
        
        # Timeouts for long-lived connections
        proxy_read_timeout 86400;
    }
}

Common Pitfalls

1. proxy_pass Trailing Slash

❌ Bad (double path):

location /api/ {
    proxy_pass http://localhost:3000;  # → http://localhost:3000/api/users
}

✅ Good (strips /api):

location /api/ {
    proxy_pass http://localhost:3000/;  # → http://localhost:3000/users
}

2. Missing try_files for SPA

❌ Bad (404 on client routes):

location / {
    root /var/www/app;
}

✅ Good (SPA fallback):

location / {
    root /var/www/app;
    try_files $uri $uri/ /index.html;
}

3. SSL Certificate Chain

❌ Bad (incomplete chain):

ssl_certificate /etc/nginx/ssl/cert.pem;  # Only server cert

✅ Good (full chain):

ssl_certificate /etc/nginx/ssl/fullchain.pem;  # Cert + intermediates

4. root vs alias

❌ Bad (wrong path):

location /static {
    root /var/www/app;  # Looks for /var/www/app/static/
}

✅ Good (correct path):

location /static {
    alias /var/www/app/static/;  # Looks in /var/www/app/static/
}

5. Forgetting nginx -t

❌ Bad:

sudo systemctl reload nginx  # Breaks site if config invalid!

✅ Good:

sudo nginx -t && sudo systemctl reload nginx

Verification Checklist

Before deploying Nginx configurations:

Configuration

  • nginx -t passes (syntax valid)
  • All server names have DNS records
  • SSL certificates valid and not expired
  • HTTP to HTTPS redirect configured
  • Proxy headers set correctly

Security

  • TLS 1.2+ only (no TLS 1.0, 1.1)
  • Strong cipher suites configured
  • HSTS enabled for HTTPS sites
  • Rate limiting on sensitive endpoints
  • No server_tokens (hide Nginx version)

Performance

  • Gzip enabled for text files
  • Static assets have cache headers
  • Connection keepalive enabled
  • Worker processes match CPU cores
  • Client body size limits set

Monitoring

  • Access logs configured
  • Error logs configured
  • Log rotation enabled (logrotate)
  • Disk space for logs monitored

Integration with Other Skills

With Docker

  • Nginx container as reverse proxy
  • Volume mount for configs and SSL certs
  • Health checks in docker-compose

With Next.js

  • Proxy API routes to Next.js server
  • Serve static assets directly
  • Handle client-side routing with try_files

With Let's Encrypt

  • Certbot for automatic SSL renewal
  • HTTP-01 or DNS-01 challenges
  • Systemd timer for auto-renewal

With PostgreSQL / Redis

  • Never expose databases directly
  • Proxy through Nginx with authentication
  • Rate limit database admin interfaces

References

Official Docs

Security

Tools

Meta: Skill Quality

Completeness: ✅ Comprehensive (9/9 sections)
Karpathy Principles: ✅ 8 mentions
Code Examples: ✅ 15+ working examples
Production Tested: ✅ Used across Alteriom infrastructure
Last Updated: 2026-04-14

Coverage:

  • ✅ Reverse proxy patterns
  • ✅ SSL/TLS configuration
  • ✅ Static file serving
  • ✅ Load balancing
  • ✅ Rate limiting
  • ✅ Caching strategies
  • ✅ WebSocket proxying
  • ✅ Multi-domain setups
  • ✅ Security best practices

Skill Level: Intermediate
Time to Learn: 3-4 hours
Prerequisites Met: HTTP basics, Linux administration

Known Gaps: None - production-ready

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.