home / skills / ehtbanton / claudeskillsrepo / 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-builderReview the files below or copy the command above to add this skill to your agents.
---
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.
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/.
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.
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.