PureDevTools

Nginx Config Generator

Build Nginx server block configurations section by section — SSL, proxy pass, GZIP, caching, security headers, rate limiting, and more

All processing happens in your browser. No data is sent to any server.

Basic Settings

Space-separated. Use _ as catch-all.

SSL / TLS

HTTPS certificate and key paths (requires port 443)

Force HTTPS Redirect

Add a separate HTTP server block that 301-redirects to HTTPS

www / non-www Redirect

Redirect between www and non-www canonical URL

GZIP Compression

Compress text, CSS, JS, JSON, and SVG responses

Uses gzip_comp_level 6 — best balance between CPU and compression ratio.

Static File Caching

Set browser cache expiry for images, CSS, and JavaScript

Proxy Pass (Reverse Proxy)

Forward requests to an upstream application server

Security Headers

X-Frame-Options, X-Content-Type-Options, and HSTS

Rate Limiting

Limit requests per IP to protect against brute force and DoS

Client Max Body Size

Maximum allowed size for request bodies (file uploads)

Custom Error Pages

Serve custom HTML for 404, 403, 500, and 502 errors

Generated Nginx Confignginx.conf
# Generated by PureDevTools Nginx Config Generator
# https://puredevtools.tools/nginx-config-generator

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

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

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

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

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

    # Image caching
    location ~* \.(jpg|jpeg|png|gif|ico|webp|svg|bmp)$ {
        expires 30d;
        add_header Cache-Control "public, immutable";
    }

    # CSS caching
    location ~* \.css$ {
        expires 7d;
        add_header Cache-Control "public";
    }

    # JavaScript caching
    location ~* \.js$ {
        expires 7d;
        add_header Cache-Control "public";
    }

}

You’re deploying a Node.js app behind Nginx and need: SSL termination with Let’s Encrypt certs, HTTPS redirect, reverse proxy to localhost:3000, GZIP compression, static file caching with 30-day Cache-Control, security headers (CSP, HSTS, X-Frame-Options), and WebSocket support for your real-time features. Writing the server {} block from scratch means 80+ lines of directives with semicolons in exactly the right places.

Why This Generator (Not the .htaccess Generator)

PureDevTools has an .htaccess Generator for Apache servers. This tool generates Nginx server block configurations — toggle sections on/off for SSL, proxy pass, GZIP, caching, security headers, rate limiting, and WebSocket support. Each section is a toggle, not a text field, so you can’t introduce syntax errors. Everything runs in your browser.

What Is an Nginx Server Block?

An Nginx server block (equivalent to Apache’s virtual host) defines how Nginx handles requests for a specific domain or IP address. Each server block contains the server name, listen port, root directory, and location rules that process incoming HTTP requests.

A typical Nginx server block looks like:

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

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

Nginx reads these blocks from /etc/nginx/sites-available/ (on Debian/Ubuntu) or /etc/nginx/conf.d/ (on RHEL/CentOS) and applies them per request.

Force HTTPS with Nginx

The recommended way to redirect all HTTP traffic to HTTPS is a separate server block that issues a 301 permanent redirect:

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

This is more efficient than using rewrite because return terminates processing immediately. The $host variable ensures the redirect preserves the original hostname.

SSL/TLS Configuration

For HTTPS, Nginx needs an SSL certificate and private key. With Let’s Encrypt and Certbot:

server {
    listen 443 ssl;
    server_name example.com;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;
}

TLSv1.2 and TLSv1.3 are the only secure protocol versions. TLSv1.0 and TLSv1.1 are deprecated (CVE vulnerabilities, browser warnings). The HIGH:!aNULL:!MD5 cipher suite excludes anonymous and MD5-based ciphers.

Nginx Reverse Proxy Configuration

The most common use case for Nginx in modern application stacks is as a reverse proxy — Nginx receives the HTTP request and forwards it to your application server (Node.js, Python, Go, etc.):

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

The proxy_set_header directives pass the original client information to your application, so it can log real IP addresses and detect whether the original request was HTTP or HTTPS.

WebSocket Proxy with Nginx

WebSocket connections require an HTTP upgrade handshake. Add these headers to your proxy location:

location / {
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_pass http://127.0.0.1:3000;
}

The Upgrade and Connection: upgrade headers instruct Nginx to pass the WebSocket upgrade request to the backend rather than closing the connection after the first response.

GZIP Compression

Enabling GZIP reduces response sizes by 60-80% for text-based content, significantly improving page load speed:

gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css application/json application/javascript text/xml;

gzip_comp_level 6 is the recommended balance between compression ratio and CPU usage. Level 9 uses significantly more CPU for marginal gains. gzip_vary on adds a Vary: Accept-Encoding header so CDNs and proxies cache both compressed and uncompressed versions.

Static File Caching

Browser caching eliminates redundant requests for assets that rarely change. Nginx’s expires directive sets Cache-Control and Expires headers:

location ~* \.(jpg|jpeg|png|gif|ico|webp|svg)$ {
    expires 30d;
    add_header Cache-Control "public, immutable";
}

location ~* \.css$ {
    expires 7d;
    add_header Cache-Control "public";
}

location ~* \.js$ {
    expires 7d;
    add_header Cache-Control "public";
}

Use immutable for content-hashed assets (like webpack bundles) — it tells browsers never to revalidate the file, even on forced reload. For un-hashed assets like style.css, omit immutable so browsers can revalidate when the cache expires.

Security Headers

HTTP security headers protect against common web attacks. Each header serves a specific purpose:

HeaderPurpose
X-Frame-Options: SAMEORIGINPrevents clickjacking — blocks your page from being embedded in iframes on other domains
X-Content-Type-Options: nosniffPrevents MIME-type sniffing — browsers must use the declared Content-Type
Strict-Transport-SecurityHSTS — instructs browsers to always use HTTPS for your domain
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

The always keyword ensures headers are added even for error responses (4xx, 5xx), not just 2xx responses.

HSTS Warning: Once you set HSTS with a high max-age, browsers will refuse HTTP connections for that duration. Test on staging before enabling on production. Start with max-age=2592000 (30 days) before increasing to 1 year.

Rate Limiting

Nginx’s limit_req module protects your server from brute force attacks, credential stuffing, and DoS attempts:

# In http {} block (nginx.conf):
limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s;

# In server {} block:
limit_req zone=req_limit burst=20 nodelay;
limit_req_status 429;

The zone definition allocates 10MB of shared memory (stores ~160,000 IP addresses). burst=20 allows bursts of up to 20 requests above the rate limit. nodelay processes burst requests immediately rather than queuing them. limit_req_status 429 returns the standard HTTP 429 Too Many Requests instead of the default 503.

Client Max Body Size

By default, Nginx limits request body size to 1MB. Increase this for file upload endpoints:

client_max_body_size 10m;

Set this to slightly above your maximum expected upload size. Setting it too high wastes memory and opens your server to large payload attacks.

Canonical URLs: www vs non-www

Serving from both example.com and www.example.com creates duplicate content in search engines. Force one canonical version:

Force non-www (modern standard):

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

Force www:

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

The SSL certificate must also cover the redirect domain (www.example.com) — either as a SAN (Subject Alternative Name) or wildcard certificate.

Related Tools

More DevOps & Networking Tools