Zero Signup ToolsFree browser tools

Developer Tools

Nginx Config Generator

Generate a production nginx server block for static sites, SPAs, reverse proxies, PHP-FPM, or load-balanced upstreams. Modern TLS, HSTS, gzip, HTTP/2.

Site type

Pick what nginx is serving

Each preset switches the location blocks and defaults to match a common nginx deployment pattern.

Serve files but fall back to /index.html so a client-side router handles unknown paths. Use for React, Vue, Svelte, Angular, SolidJS, and Remix client routes.

Hostname and ports

server_name and listen

Space-separated host list. Use a single hostname unless you intentionally want to serve both apex and www from one block.

Usually 80. Change only if nginx sits behind another proxy that already terminates on 80.

Usually 443. Used for the ssl listen lines and HTTPS redirect.

TLS

Modern HTTPS profile

Path to the full chain (Let's Encrypt emits this as fullchain.pem).

Path to the private key. Permissions must be 600 and owned by root.

Document root

Where files live on disk

Absolute path. Make sure the nginx user can read it (usually www-data or nginx).

Space-separated list. nginx serves the first one it finds.

Hardening

Headers and behavior toggles

0 means unlimited. nginx default is 1 MB.

Emits a second server block that 301-redirects to the canonical hostname.

Output

nginx.conf

Save to /etc/nginx/conf.d/example.com.conf, then run nginx -t and reload.

# Generated by Zero Signup Tools / Nginx Config Generator
# Drop into /etc/nginx/conf.d/ or /etc/nginx/sites-available/ and
# enable it with: nginx -t && systemctl reload nginx

# HTTP server: redirect every request to HTTPS so nothing leaks in plaintext.
server {
    listen 80;
    listen [::]:80;
    server_name example.com;

    # Let's Encrypt HTTP-01 challenges keep working even mid-redirect.
    location /.well-known/acme-challenge/ {
        root /var/www/letsencrypt;
    }

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

# Primary server block.
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name example.com;

    # TLS. The full chain plus private key emitted by Let's Encrypt
    # (or any modern CA). Set permissions to 600 on the key file.
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    # Modern TLS profile. TLS 1.2 + 1.3 only, no weak ciphers.
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers off;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 1d;
    ssl_session_tickets off;
    # OCSP stapling so clients can verify the cert without an extra round trip.
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 1.1.1.1 8.8.8.8 valid=300s;
    resolver_timeout 5s;

    root /var/www/example.com/dist;
    index index.html;

    # Hide the nginx version in error pages and the Server header.
    server_tokens off;

    # Cap upload size. Set to 0 for unlimited (not recommended).
    client_max_body_size 10m;

    # Gzip compression. Brotli is generally better but requires the
    # ngx_brotli module; uncomment the brotli lines if you have it.
    gzip on;
    gzip_vary on;
    gzip_comp_level 6;
    gzip_min_length 1024;
    gzip_proxied any;
    gzip_types
        text/plain
        text/css
        text/xml
        text/javascript
        application/javascript
        application/x-javascript
        application/json
        application/xml
        application/xml+rss
        application/rss+xml
        application/atom+xml
        application/wasm
        image/svg+xml
        font/ttf
        font/otf;
    # brotli on;
    # brotli_comp_level 5;
    # brotli_types text/plain text/css application/javascript application/json image/svg+xml;

    # Security headers. Tune for your site, especially if you embed cross-origin
    # content. always = also send the header on error responses (4xx, 5xx).
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;
    add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;
    add_header Cross-Origin-Opener-Policy "same-origin" always;
    # HSTS. Includes subdomains and preload. Remove preload if you have not
    # submitted to hstspreload.org. Max-age is two years.
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;

    # Access and error logs. Rotate via /etc/logrotate.d/nginx (default on
    # most distros).
    access_log /var/log/nginx/example.com.access.log;
    error_log  /var/log/nginx/example.com.error.log warn;

    # Deny access to dotfiles (.git, .env, .htaccess, etc.). Always.
    location ~ /\.(?!well-known) {
        deny all;
        access_log off;
        log_not_found off;
    }

    # Long cache for static assets that change filename on update
    # (hashed JS / CSS / font / image bundles).
    location ~* \.(?:css|js|woff2?|ttf|otf|eot|ico|png|jpe?g|gif|webp|avif|svg|mp4|webm|map)$ {
        add_header Cache-Control "public, max-age=31536000, immutable" always;
        access_log off;
        try_files $uri =404;
    }

    # Single-page app: serve files, fall back to /index.html so the router
    # can handle the route in the browser.
    location / {
        try_files $uri $uri/ /index.html;
    }
}

Review

Looks good

Modern TLS, HTTP/2, HSTS, security headers, gzip, deny dotfiles, and long-cache for static assets are all on. Ready to commit.

Reload

Quick commands

# Test the config before reloading
sudo nginx -t
# Reload without dropping connections
sudo systemctl reload nginx
# Tail the access log for this site
sudo tail -f /var/log/nginx/example.com.access.log

Why these defaults

A short tour of the choices baked in

  • Modern TLS profile

    TLS 1.2 and 1.3 only, OCSP stapling, session caching, and the Mozilla intermediate cipher list. Drops every weak suite a scanner will complain about.

  • HTTPS redirect that survives ACME

    The port 80 server keeps /.well-known/acme-challenge open so Let's Encrypt renewals never break, then redirects everything else to HTTPS.

  • Proxy headers preserve the client

    X-Real-IP, X-Forwarded-For, X-Forwarded-Proto, Host, and Upgrade all forwarded. Frameworks behind nginx see the real client IP and scheme.

  • Cache hashed assets aggressively

    Hashed CSS, JS, fonts, and images get a one-year immutable cache. Cuts repeat-visit bandwidth without risking stale content since the filename changes on every deploy.

  • Security headers on by default

    X-Content-Type-Options, Referrer-Policy, Permissions-Policy, and Cross-Origin-Opener-Policy plug the most common scanner findings. HSTS is opt-in until you have verified TLS works.

  • Dotfile and version leaks blocked

    Requests to /.git, /.env, and /.htaccess are denied. server_tokens off hides the nginx version in the Server header so bots cannot target known CVEs by build.

How to use

  1. Pick what nginx is serving: static site, single-page app, reverse proxy, PHP-FPM, or load-balanced upstreams.
  2. Set the hostname (server_name), HTTP port, and HTTPS port. server_name supports a space-separated list.
  3. Configure TLS: paste the ssl_certificate full chain path and ssl_certificate_key path, then leave HTTP/2 and HTTPS redirect on.
  4. Fill in the type-specific fields. Static and SPA need a document root. Reverse proxy needs an upstream URL with scheme. PHP-FPM needs the FastCGI socket. Load balancing needs an upstream pool name plus host:port rows.
  5. Toggle hardening options: security headers, gzip, deny dotfiles, long cache for hashed assets, server_tokens off, access and error logs, custom error pages, HTTP Basic auth, CORS, and the www redirect direction.
  6. Read the Review panel under the output. Fix any errors, then copy the config to a file like /etc/nginx/conf.d/your-site.conf.
  7. Run sudo nginx -t to validate the syntax, then sudo systemctl reload nginx to apply without dropping live connections.

About this tool

Nginx Config Generator builds a complete, production-leaning nginx server block from a small set of choices: site type (static site, single-page app, reverse proxy, PHP-FPM, or load-balanced upstream pool), hostname, ports, TLS settings, document root, upstream URL, and a handful of best-practice toggles. The output mirrors the layout most production nginx deployments converge on. A port 80 server keeps /.well-known/acme-challenge open for Let's Encrypt and 301-redirects everything else to HTTPS. A port 443 server pins a modern TLS profile (TLS 1.2 and 1.3 only, Mozilla intermediate ciphers, OCSP stapling, session caching) and adds HTTP/2 to the listen line. Proxy modes forward Host, X-Real-IP, X-Forwarded-For, X-Forwarded-Proto, and the Upgrade and Connection headers so frameworks behind nginx see the real client and websockets keep working. Security headers (X-Content-Type-Options, X-Frame-Options, Referrer-Policy, Permissions-Policy, Cross-Origin-Opener-Policy, optional HSTS) are on by default, gzip compresses the right text MIME types, hashed static assets get a one-year immutable cache, and dotfile leaks (.git, .env, .htaccess) are denied while leaving /.well-known alone for ACME. A review panel surfaces common mistakes such as a missing absolute path on ssl_certificate, server_name empty, HSTS turned on without TLS, or CORS Allow-Origin set to wildcard with credentialed expectations, so the config is safe to drop into /etc/nginx/conf.d/ and reload. Building is pure string templating in your browser, no upload, no external API, no tracking. Run nginx -t to validate before reloading.

Free to use. Works in your browser. No signup, no login.

Related tools

You may also like

All tools
All toolsDeveloper Tools