home / skills / ehtbanton / claudeskillsrepo / nginx-config-builder

nginx-config-builder skill

/nginx-config-builder

This skill generates production-ready NGINX configurations for static sites, reverse proxies, load balancers, and PHP/Node.js apps with secure defaults.

npx playbooks add skill ehtbanton/claudeskillsrepo --skill nginx-config-builder

Review the files below or copy the command above to add this skill to your agents.

Files (2)
SKILL.md
11.2 KB
---
name: nginx-config-builder
description: Generate NGINX configuration files for web servers, reverse proxies, load balancing, SSL termination, and static file serving. Triggers on "create nginx config", "generate nginx.conf", "nginx configuration for", "reverse proxy config".
---

# NGINX Config Builder

Generate production-ready NGINX configuration files for various web server scenarios.

## Output Requirements

**File Output:** `nginx.conf`, `default.conf`, `site.conf`
**Format:** Valid NGINX configuration syntax
**Location:** Typically `/etc/nginx/` or `/etc/nginx/conf.d/`

## When Invoked

Immediately generate a complete, valid NGINX configuration. Include security headers, optimization settings, and logging by default.

## Configuration Templates

### Basic Static Website
```nginx
# /etc/nginx/conf.d/static-site.conf

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

    # Redirect HTTP to HTTPS
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name example.com www.example.com;

    # SSL Configuration
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    ssl_session_tickets off;

    # Modern SSL configuration
    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
    add_header Strict-Transport-Security "max-age=63072000" always;

    # Document root
    root /var/www/example.com/public;
    index index.html index.htm;

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

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

    # Gzip compression
    gzip on;
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_types text/plain text/css text/xml application/json application/javascript application/rss+xml application/atom+xml image/svg+xml;

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

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

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

### Reverse Proxy (Node.js/Express)
```nginx
# /etc/nginx/conf.d/app.conf

upstream nodejs_backend {
    server 127.0.0.1:3000;
    keepalive 64;
}

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

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

    # SSL Configuration
    ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;

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

    # Security headers
    add_header X-Frame-Options "DENY" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;

    # Client body size (for file uploads)
    client_max_body_size 10M;

    # Proxy settings
    location / {
        proxy_pass http://nodejs_backend;
        proxy_http_version 1.1;

        # 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 support
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

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

    # Health check endpoint (no logging)
    location /health {
        access_log off;
        proxy_pass http://nodejs_backend;
    }
}
```

### Load Balancer
```nginx
# /etc/nginx/conf.d/loadbalancer.conf

upstream app_servers {
    # Load balancing method (round-robin is default)
    # Options: least_conn, ip_hash, hash
    least_conn;

    # Backend servers
    server 10.0.0.1:8080 weight=5;
    server 10.0.0.2:8080 weight=3;
    server 10.0.0.3:8080 weight=2;

    # Backup server
    server 10.0.0.4:8080 backup;

    # Health checks
    keepalive 32;
}

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

    location / {
        proxy_pass http://app_servers;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        # Sticky sessions (if needed)
        # proxy_set_header X-Session-ID $cookie_sessionid;

        # Retry on failure
        proxy_next_upstream error timeout http_500 http_502 http_503;
        proxy_next_upstream_tries 3;
    }
}
```

### SPA (React/Vue/Angular) with API Proxy
```nginx
# /etc/nginx/conf.d/spa.conf

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

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

    ssl_certificate /etc/letsencrypt/live/app.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/app.example.com/privkey.pem;

    root /var/www/app/dist;
    index index.html;

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

    # Static assets with long cache
    location /assets/ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }

    # API proxy
    location /api/ {
        proxy_pass http://127.0.0.1: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;
    }

    # WebSocket proxy
    location /ws/ {
        proxy_pass http://127.0.0.1:3000/ws/;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
    }

    # SPA fallback - serve index.html for all routes
    location / {
        try_files $uri $uri/ /index.html;

        # Don't cache index.html
        add_header Cache-Control "no-store, no-cache, must-revalidate";
    }
}
```

### PHP-FPM (WordPress/Laravel)
```nginx
# /etc/nginx/conf.d/php-app.conf

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

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

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

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

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

    # Security
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;

    # File upload size
    client_max_body_size 64M;

    # Gzip
    gzip on;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml;

    # Main location
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    # PHP handling
    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.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;

        # Timeouts
        fastcgi_connect_timeout 60;
        fastcgi_send_timeout 180;
        fastcgi_read_timeout 180;
        fastcgi_buffer_size 128k;
        fastcgi_buffers 4 256k;
    }

    # Static file caching
    location ~* \.(jpg|jpeg|png|gif|ico|css|js|pdf|woff|woff2)$ {
        expires 30d;
        add_header Cache-Control "public";
    }

    # Deny access to sensitive files
    location ~ /\.(ht|git|env) {
        deny all;
    }

    location ~ ^/(vendor|storage)/ {
        deny all;
    }
}
```

### Rate Limiting & Security
```nginx
# /etc/nginx/conf.d/security.conf

# Rate limiting zones
limit_req_zone $binary_remote_addr zone=general:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=login:10m rate=1r/s;
limit_req_zone $binary_remote_addr zone=api:10m rate=100r/s;

# Connection limiting
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;

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

    # Connection limit
    limit_conn conn_limit 20;

    # General rate limiting
    location / {
        limit_req zone=general burst=20 nodelay;
        # ... proxy or other config
    }

    # Strict rate limiting for login
    location /auth/login {
        limit_req zone=login burst=5 nodelay;
        # ... proxy config
    }

    # Higher limit for API
    location /api/ {
        limit_req zone=api burst=200 nodelay;
        # ... proxy config
    }

    # Block common attacks
    location ~* "(eval\(|base64_|javascript:|vbscript:|<script)" {
        deny all;
    }

    # Block SQL injection attempts
    location ~* "(union.*select|select.*from|insert.*into)" {
        deny all;
    }
}
```

## Common Patterns

### CORS Headers
```nginx
location /api/ {
    add_header Access-Control-Allow-Origin $http_origin always;
    add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
    add_header Access-Control-Allow-Headers "Authorization, Content-Type" always;
    add_header Access-Control-Allow-Credentials true always;

    if ($request_method = OPTIONS) {
        return 204;
    }
}
```

### Basic Auth
```nginx
location /admin/ {
    auth_basic "Admin Area";
    auth_basic_user_file /etc/nginx/.htpasswd;
}
```

## Validation Checklist

Before outputting, verify:
- [ ] All server blocks have `listen` directive
- [ ] SSL configs include certificate paths
- [ ] Upstream blocks define at least one server
- [ ] `root` directive points to valid path
- [ ] Security headers included
- [ ] Proper logging configured
- [ ] Syntax is valid (testable with `nginx -t`)

## Example Invocations

**Prompt:** "Create nginx config for React app with Node.js API backend"
**Output:** Complete `nginx.conf` with SPA handling, API proxy, SSL.

**Prompt:** "Generate nginx reverse proxy for 3 backend servers"
**Output:** Complete `nginx.conf` with upstream load balancing, health checks.

**Prompt:** "NGINX configuration for WordPress with caching"
**Output:** Complete `nginx.conf` with PHP-FPM, fastcgi cache, security.

Overview

This skill generates production-ready NGINX configuration files for web servers, reverse proxies, load balancers, SSL termination, static sites, SPAs, and PHP-FPM apps. It outputs valid nginx.conf / site.conf fragments with security headers, logging, gzip, caching and sensible defaults. Use it to quickly produce complete, testable configuration files ready to drop into /etc/nginx/ or /etc/nginx/conf.d/.

How this skill works

When invoked it returns a complete NGINX configuration tailored to the requested scenario (static site, reverse proxy, load balancer, SPA, PHP-FPM, etc.). Each output includes listen directives, SSL settings when requested, upstream definitions for backends, security headers, rate limits, logging paths, gzip and caching rules. The result is syntactically valid NGINX config intended to pass nginx -t after adjusting paths and certificate files.

When to use it

  • Create a secure static site configuration with HTTPS and caching
  • Generate a reverse proxy for Node.js or other backend services
  • Build a load balancer config for multiple backend servers
  • Provision SPA hosting with API and websocket proxying
  • Configure PHP-FPM sites (WordPress/Laravel) with fastcgi settings and security

Best practices

  • Always verify and replace certificate and path placeholders before deployment
  • Run nginx -t after installing the config and reload nginx gracefully (nginx -s reload)
  • Use upstream keepalive and health-aware settings for high traffic backends
  • Apply rate limiting zones for login and API endpoints to mitigate abuse
  • Separate site configs into /etc/nginx/conf.d/ and keep global security rules in a shared file

Example use cases

  • Create nginx.conf for a React SPA with an API proxied to localhost:3000 and long cache for static assets
  • Generate a reverse proxy config for a Node/Express app with websocket support and client_max_body_size for uploads
  • Produce a load balancer config using least_conn with weighted backend servers and a backup node
  • Build a WordPress NGINX config with PHP-FPM fastcgi settings and rules to deny sensitive files
  • Output a security.conf with rate limits, connection caps, and simple attack-mitigation regex blocks

FAQ

Will the generated config include SSL certificates?

Yes—templates include SSL directives and example LetsEncrypt paths, but you must replace placeholders with your actual certificate and key locations.

Are the outputs immediately safe to use in production?

Outputs follow best practices (security headers, logging, gzip, timeouts) but require validation: confirm paths, upstream servers, and run nginx -t before reloading.