nginx-config-optimizer

Nginx Config Optimizer

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "nginx-config-optimizer" with this command: npx skills add patricio0312rev/skills/patricio0312rev-skills-nginx-config-optimizer

Nginx Config Optimizer

Create optimized Nginx configurations for high-performance web serving and reverse proxying.

Core Workflow

  • Define architecture: Reverse proxy, load balancer, or static serving

  • Configure security: SSL/TLS, headers, rate limiting

  • Optimize performance: Caching, compression, buffers

  • Setup upstream: Backend server pools

  • Add monitoring: Access logs, metrics

  • Test configuration: Validate and reload

Main Configuration

/etc/nginx/nginx.conf

user nginx; worker_processes auto; worker_rlimit_nofile 65535; pid /run/nginx.pid;

Load dynamic modules

include /etc/nginx/modules-enabled/*.conf;

events { worker_connections 4096; multi_accept on; use epoll; }

http { # Basic settings sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; server_tokens off;

# Buffer settings
client_body_buffer_size 16k;
client_header_buffer_size 1k;
client_max_body_size 50m;
large_client_header_buffers 4 8k;

# Timeouts
client_body_timeout 12;
client_header_timeout 12;
send_timeout 10;

# MIME types
include /etc/nginx/mime.types;
default_type application/octet-stream;

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

log_format json escape=json '{'
    '"time_local":"$time_local",'
    '"remote_addr":"$remote_addr",'
    '"request":"$request",'
    '"status":$status,'
    '"body_bytes_sent":$body_bytes_sent,'
    '"request_time":$request_time,'
    '"upstream_response_time":"$upstream_response_time",'
    '"http_referer":"$http_referer",'
    '"http_user_agent":"$http_user_agent"'
'}';

access_log /var/log/nginx/access.log json;
error_log /var/log/nginx/error.log warn;

# Gzip compression
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 5;
gzip_min_length 256;
gzip_types
    application/atom+xml
    application/javascript
    application/json
    application/ld+json
    application/manifest+json
    application/rss+xml
    application/vnd.geo+json
    application/vnd.ms-fontobject
    application/x-font-ttf
    application/x-web-app-manifest+json
    application/xhtml+xml
    application/xml
    font/opentype
    image/bmp
    image/svg+xml
    image/x-icon
    text/cache-manifest
    text/css
    text/plain
    text/vcard
    text/vnd.rim.location.xloc
    text/vtt
    text/x-component
    text/x-cross-domain-policy
    text/xml;

# Brotli compression (if module available)
# brotli on;
# brotli_comp_level 6;
# brotli_types text/plain text/css application/json application/javascript;

# SSL settings
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;

# Security headers (global)
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;

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

# Proxy cache
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=STATIC:10m inactive=7d use_temp_path=off max_size=1g;

# Include site configs
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;

}

Reverse Proxy Configuration

/etc/nginx/sites-available/app.conf

upstream backend { least_conn; keepalive 32;

server 10.0.1.10:3000 weight=5;
server 10.0.1.11:3000 weight=5;
server 10.0.1.12:3000 weight=5 backup;

# Health checks (Nginx Plus or OpenResty)
# health_check interval=5s fails=3 passes=2;

}

upstream api { ip_hash; keepalive 64;

server 10.0.2.10:8080 max_fails=3 fail_timeout=30s;
server 10.0.2.11:8080 max_fails=3 fail_timeout=30s;

}

Redirect HTTP to HTTPS

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

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

location / {
    return 301 https://$host$request_uri;
}

}

Main HTTPS server

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_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;

# Security headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self'; connect-src 'self' https://api.example.com wss://example.com" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;

# Rate limiting
limit_req zone=general burst=20 nodelay;
limit_conn addr 10;

# Root and error pages
root /var/www/html;
error_page 500 502 503 504 /50x.html;

# Static files with caching
location /static/ {
    alias /var/www/static/;
    expires 1y;
    add_header Cache-Control "public, immutable";
    access_log off;
}

# Next.js static files
location /_next/static/ {
    alias /var/www/app/.next/static/;
    expires 1y;
    add_header Cache-Control "public, immutable";
    access_log off;
}

# Proxy to backend
location / {
    proxy_pass http://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;
    proxy_set_header X-Forwarded-Host $host;
    proxy_set_header X-Forwarded-Port $server_port;

    # WebSocket support
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";

    # Keepalive
    proxy_set_header Connection "";

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

    # Cache settings for specific responses
    proxy_cache STATIC;
    proxy_cache_valid 200 1h;
    proxy_cache_valid 404 1m;
    proxy_cache_bypass $http_cache_control;
    add_header X-Cache-Status $upstream_cache_status;
}

# API endpoints
location /api/ {
    limit_req zone=api burst=50 nodelay;

    proxy_pass http://api/;
    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;
    proxy_set_header Connection "";

    # Longer timeout for API
    proxy_read_timeout 120s;

    # No caching for API
    proxy_cache off;
    add_header Cache-Control "no-store";
}

# Login rate limiting
location /api/auth/login {
    limit_req zone=login burst=5 nodelay;

    proxy_pass http://api/auth/login;
    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 endpoint
location /ws {
    proxy_pass http://backend;
    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_read_timeout 3600s;
    proxy_send_timeout 3600s;
}

# Health check endpoint
location /health {
    access_log off;
    return 200 'OK';
    add_header Content-Type text/plain;
}

# Deny access to sensitive files
location ~ /\. {
    deny all;
    access_log off;
    log_not_found off;
}

location ~ ^/(\.env|composer\.json|package\.json|yarn\.lock) {
    deny all;
}

}

Load Balancer Configuration

/etc/nginx/conf.d/load-balancer.conf

upstream app_cluster { # Load balancing methods: # round_robin (default) # least_conn - least number of active connections # ip_hash - session persistence by IP # hash $request_uri consistent - consistent hashing

least_conn;

server 10.0.1.10:3000 weight=10 max_fails=3 fail_timeout=30s;
server 10.0.1.11:3000 weight=10 max_fails=3 fail_timeout=30s;
server 10.0.1.12:3000 weight=5 max_fails=3 fail_timeout=30s;
server 10.0.1.13:3000 backup;

keepalive 100;

}

Active health checks (Nginx Plus)

match server_ok {

status 200-399;

body ~ "OK";

}

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

ssl_certificate /etc/nginx/ssl/app.crt;
ssl_certificate_key /etc/nginx/ssl/app.key;

location / {
    proxy_pass http://app_cluster;
    proxy_http_version 1.1;
    proxy_set_header Connection "";

    # Sticky sessions using cookie
    # sticky cookie srv_id expires=1h domain=.example.com path=/;

    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_next_upstream error timeout http_500 http_502 http_503 http_504;
    proxy_next_upstream_tries 3;
    proxy_next_upstream_timeout 10s;

    # Health check (Nginx Plus)
    # health_check match=server_ok interval=5s fails=3 passes=2;
}

}

Caching Configuration

/etc/nginx/conf.d/cache.conf

FastCGI cache (for PHP)

fastcgi_cache_path /var/cache/nginx/fastcgi levels=1:2 keys_zone=FASTCGI:100m inactive=60m max_size=1g; fastcgi_cache_key "$scheme$request_method$host$request_uri";

Proxy cache for static content

proxy_cache_path /var/cache/nginx/proxy levels=1:2 keys_zone=PROXY:100m inactive=7d max_size=10g use_temp_path=off;

Microcaching for dynamic content

proxy_cache_path /var/cache/nginx/micro levels=1:2 keys_zone=MICRO:10m inactive=1m max_size=100m;

map $request_uri $cache_bypass { default 0; ~^/api/ 1; ~^/admin/ 1; }

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

# Serve cached static files
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff2|woff|ttf|svg|webp|avif)$ {
    proxy_pass http://origin;
    proxy_cache PROXY;
    proxy_cache_valid 200 30d;
    proxy_cache_valid 404 1m;
    proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
    proxy_cache_background_update on;
    proxy_cache_lock on;

    add_header X-Cache-Status $upstream_cache_status;
    add_header Cache-Control "public, max-age=2592000, immutable";

    expires 30d;
}

# Microcaching for HTML
location / {
    proxy_pass http://backend;
    proxy_cache MICRO;
    proxy_cache_valid 200 1s;
    proxy_cache_bypass $cache_bypass;
    proxy_no_cache $cache_bypass;
    proxy_cache_use_stale updating;
    proxy_cache_background_update on;

    add_header X-Cache-Status $upstream_cache_status;
}

}

Security Hardening

/etc/nginx/conf.d/security.conf

Block bad bots

map $http_user_agent $bad_bot { default 0; ~malicious 1; ~scanner 1; ~*bot 1; }

Block by IP (geo module)

geo $blocked_ip { default 0; 10.0.0.0/8 0; # Allow internal 192.168.0.0/16 0; # Allow internal # 1.2.3.4 1; # Block specific IP }

Rate limiting by request type

map $request_method $limit_key { POST $binary_remote_addr; default ""; }

limit_req_zone $limit_key zone=post_limit:10m rate=5r/s;

server { # Reject bad bots if ($bad_bot) { return 403; }

# Reject blocked IPs
if ($blocked_ip) {
    return 403;
}

# Block common attack patterns
location ~* "(eval\(|base64_|javascript:)" {
    return 403;
}

location ~* "(\.\./|\.\.\\)" {
    return 403;
}

# Limit POST requests
location / {
    limit_req zone=post_limit burst=10 nodelay;
    # ... rest of config
}

# Fail2ban integration - log failed attempts
location /api/auth {
    access_log /var/log/nginx/auth.log;
    # ... rest of config
}

}

Docker Nginx Configuration

nginx/nginx.conf for Docker

events { worker_connections 1024; }

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

# Logging to stdout/stderr for Docker
access_log /dev/stdout;
error_log /dev/stderr warn;

upstream app {
    server app:3000;
}

server {
    listen 80;

    location / {
        proxy_pass http://app;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

}

Dockerfile

FROM nginx:alpine

COPY nginx.conf /etc/nginx/nginx.conf COPY default.conf /etc/nginx/conf.d/default.conf

EXPOSE 80 443

HEALTHCHECK --interval=30s --timeout=3s
CMD wget --quiet --tries=1 --spider http://localhost/health || exit 1

Testing Configuration

Test configuration syntax

nginx -t

Test configuration with specific file

nginx -t -c /etc/nginx/nginx.conf

Check configuration details

nginx -T

Reload configuration without downtime

nginx -s reload

Test with curl

curl -I https://example.com curl -w "@curl-format.txt" -o /dev/null -s https://example.com

Test SSL configuration

openssl s_client -connect example.com:443 -servername example.com

Test HTTP/2

curl --http2 -I https://example.com

Best Practices

  • Worker processes: Set to auto for CPU cores

  • Keepalive connections: Enable for upstreams

  • Gzip compression: Enable for text content

  • SSL/TLS: Use TLS 1.2+ only

  • Security headers: Add HSTS, CSP, etc.

  • Rate limiting: Protect against abuse

  • Buffer tuning: Optimize for traffic patterns

  • Caching: Use proxy cache for static content

Output Checklist

Every Nginx configuration should include:

  • Worker process optimization

  • Gzip compression enabled

  • SSL/TLS with modern ciphers

  • Security headers (HSTS, CSP, X-Frame-Options)

  • Rate limiting zones

  • Upstream keepalive connections

  • Proper logging (JSON format)

  • Health check endpoints

  • Static file caching

  • Proxy buffering tuned

  • Error pages configured

  • Configuration tested with nginx -t

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

framer-motion-animator

No summary provided by upstream source.

Repository SourceNeeds Review
General

eslint-prettier-config

No summary provided by upstream source.

Repository SourceNeeds Review
General

postman-collection-generator

No summary provided by upstream source.

Repository SourceNeeds Review
General

dockerfile-optimizer

No summary provided by upstream source.

Repository SourceNeeds Review