Nginx Config Generator
Interactively generate secure, high-performance Nginx configuration files.
Fill in the form and click "Generate Config"
Common Directives
Quick reference for Nginx server block directives used in generated configs
listenSpecifies the port and protocol — 80 for HTTP, 443 ssl http2 for HTTPS.
server_nameDefines which domains this server block responds to. Supports wildcards like *.example.com.
rootSets the root directory for static files. Nginx resolves the URI path from here.
proxy_passThe upstream backend URL for reverse proxying, e.g. http://127.0.0.1:3000.
gzipEnables response compression. Greatly reduces transfer size for text assets (HTML/CSS/JS).
ssl_certificatePath to TLS certificate and private key. Let's Encrypt certs live in /etc/letsencrypt/live/.
try_filesTries paths in order. SPAs use $uri $uri/ /index.html to fall back to the frontend router.
expiresSets Cache-Control and Expires headers. Use 30d or 1y for static assets.
add_headerAppends custom response headers, commonly used for security: X-Frame-Options, HSTS, etc.
Configuration
Fill in your domain and port, enable features as needed
What is the Nginx Config Generator?
Nginx (pronounced "engine-x") is one of the most widely used web servers, reverse proxies, and load balancers in the world. It powers over 30% of all websites and is a cornerstone of modern cloud-native infrastructure. However, writing correct Nginx configuration from scratch requires deep familiarity with complex directive syntax — a process that is often time-consuming and error-prone.
This generator eliminates that friction by providing an interactive form that instantly produces a production-ready nginx.conf server block. You can easily configure domain names, listen ports, SSL/TLS termination with certificate paths, reverse proxy settings to forward traffic to backend services, Gzip compression, and static file caching.
How to use this tool
Fill in your "Server Name" (domain), choose the "Listen Port" (default 80), and enable features as needed. If you enable SSL, provide the paths to your certificate and private key files (we recommend using Certbot to obtain free Let's Encrypt certificates). If you enable reverse proxy, enter your backend service URL (e.g., http://127.0.0.1:3000 for a Node.js app). Enabling Gzip saves bandwidth, and static file caching boosts performance for asset-heavy sites.
Click "Generate Config" to produce a complete server block. Once generated, copy it to /etc/nginx/sites-available/your-domain.conf, symlink it to sites-enabled, run nginx -t to test the syntax, and reload with sudo systemctl reload nginx. Always carefully review the output before pushing to production.
Typical Production Scenarios
root + try_filesFor static HTML/CSS/JS sites or documentation hosting, point root at the build output directory (e.g. /var/www/html) and use try_files $uri $uri/ /index.html as a fallback. Configure a separate location block for static assets with long-term caching (expires 1y; Cache-Control: public, immutable). Combine with gzip on to reduce JS/CSS transfer sizes by 60–80%.
try_files $uri /index.htmlSingle-page applications (React, Vue, Angular) require all non-file routes to fall back to index.html for client-side routing — use try_files $uri $uri/ /index.html. Hashed bundle files (app.a1b2c3.js) can be cached for 1 year with Cache-Control: public, immutable. index.html itself must be no-cache or very short max-age so users immediately pick up new deployments — a common mistake is applying long-term cache to index.html, causing stale entry points after deploys.
proxy_passThe most common pattern: Nginx listens on 80/443 and proxy_pass forwards to a local app port (e.g. http://127.0.0.1:3000). You must set proxy_http_version 1.1 and forward Host, X-Real-IP, and X-Forwarded-For headers — otherwise your backend cannot see the real client IP. proxy_cache_bypass $http_upgrade prevents WebSocket upgrade requests from being intercepted by cache. Set proxy_connect_timeout 5s and proxy_read_timeout 60s to surface upstream failures quickly.
ssl_certificateA standard HTTPS setup uses two server blocks: one listening on 443 with ssl_certificate, ssl_protocols TLSv1.2 TLSv1.3, ssl_ciphers HIGH:!aNULL:!MD5, and ssl_session_cache shared:SSL:10m; a second listening on 80 that simply returns 301 https://$host$request_uri. Use Let's Encrypt + Certbot for free, auto-renewing certificates. Enable OCSP Stapling (ssl_stapling on; ssl_stapling_verify on) to pre-fetch certificate status, reducing TLS handshake round trips for clients.
Upgrade $http_upgradeWebSocket requires Nginx to forward the HTTP Upgrade handshake: set proxy_http_version 1.1, proxy_set_header Upgrade $http_upgrade, and proxy_set_header Connection "upgrade". The default proxy_read_timeout of 60s will terminate idle connections — increase to 3600s or more for persistent connections. With multiple backend instances, ensure session affinity (ip_hash or a consistent header hash) so each WebSocket session routes to the same upstream throughout its lifetime.
upstream { }Define an upstream block in the http context listing all backend nodes, then reference it with proxy_pass. Round-robin works well for stateless services; least_conn suits workloads with high variance in response time; ip_hash provides session affinity without external session storage, but reshuffles when nodes are added or removed. Each server entry should include max_fails=3 fail_timeout=30s for passive health checking — nodes exceeding the failure threshold are temporarily removed from rotation.
Performance and Security Considerations
Set worker_processes to auto (matching CPU core count) and raise worker_connections from the default 1024 to 4096 or higher in production; combine with use epoll on Linux for efficient connection handling. Keep gzip_comp_level between 4 and 6 — higher levels burn CPU for negligible bandwidth gains. For static file delivery, enable sendfile on for kernel-level zero-copy transfers and tcp_nopush on to coalesce small packets, significantly reducing TCP round trips when used together.
On the SSL/TLS side, ssl_session_cache shared:SSL:10m enables session reuse across workers, reducing repeated handshake overhead; ssl_session_timeout 1d extends the reuse window. Enable OCSP Stapling (ssl_stapling on; ssl_stapling_verify on) so Nginx pre-fetches and caches the certificate revocation status, sparing clients an extra round trip during the TLS handshake. Only allow TLSv1.2 and TLSv1.3, and exclude weak cipher suites (!aNULL !MD5 !RC4).
Rate limiting is essential defense against brute-force and application-layer DDoS. Define a shared memory zone in the http block — limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s — and apply it on sensitive locations with limit_req zone=api burst=20 nodelay. For login and registration endpoints, use a much tighter rate (e.g. 2r/m). Also configure client_max_body_size to cap upload size and prevent large requests from exhausting worker memory.
location Matching Rules & the proxy_pass Trailing-Slash Trap
location matching priority is widely misunderstood and routinely sends requests to the wrong block. From highest to lowest: = exact match wins first, then ^~ prefix match (which stops regex evaluation once hit), then ~ and ~* regex matches (case-sensitive and insensitive, evaluated in written order), and finally plain prefix matches (longest match wins). A classic trap: you add a regex location to give js, css and images long-lived caching, but an earlier regex block intercepts them first — switch the static block to a ^~ prefix match, or reorder your regex blocks, to fix it.
Whether proxy_pass ends with a slash changes its behavior completely — the single most common reverse-proxy mistake. When location /api/ proxies to http://backend/ (trailing slash), the /api/ prefix is stripped and the backend receives /; when it proxies to http://backend (no slash), the full /api/ path is forwarded as-is. Omit the slash to keep the path prefix, add it to strip the prefix. Note that as soon as proxy_pass contains any URI part (even just a /), Nginx performs path replacement.
Troubleshooting Common Errors: 502 / 504 / 413
502 Bad Gateway means Nginx received the request but could not reach the upstream. Check in order: (1) confirm the upstream process is actually listening (ss -ltnp); (2) verify the host and port in proxy_pass; (3) if the upstream is local yet still 502, SELinux or a firewall is usually blocking Nginx-to-upstream connections (setsebool -P httpd_can_network_connect 1); (4) if upstream uses a hostname, confirm DNS resolves. The connect() failed lines in /var/log/nginx/error.log point straight to the cause.
504 Gateway Timeout means the upstream responded too slowly, past the timeout threshold. Raise proxy_connect_timeout, proxy_read_timeout and proxy_send_timeout (all default to 60s) — but investigate why the upstream is slow rather than just masking it. 413 Request Entity Too Large means the upload exceeded client_max_body_size (default just 1m); raise it in the http or location block, e.g. client_max_body_size 50m for an upload endpoint, and remember this is the Nginx-layer limit — your backend may impose its own size cap that also needs raising.