Nginx Config Generator

Production-ready server blocks in seconds, not Stack Overflow tabs.

Configure

After copying: save to /etc/nginx/sites-available/, symlink into sites-enabled, then run nginx -t && systemctl reload nginx.

What an Nginx Server Block Does

Every website nginx serves is described by a server block: a declaration of which domain names it answers to, which port it listens on, and how each request path is handled. The three patterns in this generator cover the vast majority of real deployments. A static site serves files from disk. A reverse proxy forwards requests to an application (Node, Python, Go) running on localhost. A PHP site hands .php files to PHP-FPM. Choosing the wrong pattern is the root cause of most nginx confusion — so start by naming yours.

Pattern 1: Static Sites

The static pattern is the simplest and fastest: a root directory, an index file, and a try_files directive that serves the exact file or a clean 404. Because nginx serves these files directly from disk with sendfile, static sites handle enormous traffic on tiny servers. Single-page applications need one tweak — try_files $uri $uri/ /index.html — so client-side routes do not 404 on refresh. The generator emits the classic variant; add the SPA fallback if your framework handles routing in the browser.

Static block anatomy

listen 80 binds the HTTP port. server_name lists the domains — always include both the bare domain and www, or redirect one to the other to avoid duplicate content. root points at the directory holding your files; a trailing-slash mistake here is a classic 403 source. The location / block with try_files is what makes nginx a file server rather than a proxy.

Pattern 2: Reverse Proxy

Most modern applications do not let nginx serve anything directly. Instead, your Node, Django, Rails or Go process listens on localhost:3000 (or a Unix socket), and nginx — battle-hardened at accepting internet traffic — forwards each request to it. This split of responsibilities is the standard production architecture: nginx terminates TLS, serves static assets, rate-limits and buffers slow clients, while your app focuses purely on application logic.

Three proxy directives matter most. proxy_pass is the destination — note the trailing-slash semantics: proxy_pass http://localhost:3000/ with a slash rewrites the URI, without it passes the full path through. proxy_set_header Host $host preserves the original hostname, which frameworks need for URL generation and virtual hosting. X-Real-IP and X-Forwarded-For preserve the client address for logging and rate limiting, since your app would otherwise see every request as coming from 127.0.0.1.

Proxy pitfalls

Pattern 3: PHP via PHP-FPM

PHP does not run inside nginx; it runs in a separate PHP-FPM process pool, and nginx forwards .php requests to it over a Unix socket (or TCP). The location ~ \.php$ block is the handoff: fastcgi_pass points at the socket, and the fastcgi_params include file sets the CGI variables PHP expects. The try_files $uri =404 guard inside the PHP location is a security essential — without it, a crafted request can trick nginx into executing arbitrary uploaded files as PHP.

Match the socket path to your installed PHP version (php8.2-fpm.sock, php8.3-fpm.sock, and so on) — a version mismatch after an OS upgrade is one of the most common causes of sudden 502 Bad Gateway errors on PHP sites. The generator emits the 8.2 path; adjust to taste.

Adding HTTPS the Right Way

The SSL toggle adds a 443 listener with certificate paths. In practice, almost nobody writes these by hand anymore: Certbot's nginx plugin obtains free Let's Encrypt certificates and edits your server blocks automatically, including renewal. The generated snippet shows you what Certbot produces so you can read and verify it — ssl_certificate pointing at the fullchain.pem, ssl_certificate_key at the privkey.pem, plus a redirect from port 80 to 443 that the generator's HTTP block pairs with.

Two HTTPS details worth knowing: always redirect all HTTP traffic to HTTPS (never serve the same content on both), and enable HTTP/2 with a single listen 443 ssl http2 directive — it is a free performance upgrade for modern browsers.

Testing and Reloading Safely

Never reload nginx blind. The ritual is: nginx -t to test the configuration syntax, then systemctl reload nginx (not restart — reload keeps existing connections alive). A failed -t tells you the exact file and line number; fix it before reloading. Keep known-good configs in version control, and for critical sites, test with nginx -T, which dumps the entire effective configuration so you can see exactly what nginx thinks you asked for.

Reading nginx errors

How This Generator Helps

NginxConf removes the blank-page problem: pick static, reverse proxy or PHP in the rail, enter your domain, toggle SSL, and copy a clean, commented server block — or download it as a .conf file ready to drop into sites-available. Learn the patterns once from the generated output, then customise with confidence.

From Config to Production: A Checklist

A generated server block is the start, not the finish. Work through this before going live: place the file in sites-available and symlink it into sites-enabled; run nginx -t and fix every warning; reload (never restart) so existing connections survive; test the domain with curl -I to confirm the right block answers; verify HTTPS redirects; check the certificate expiry and enable auto-renewal; confirm your app receives the X-Forwarded headers it needs; load-test the proxy timeouts with a slow endpoint; and set up log rotation so access logs do not fill the disk. The generator's tip line covers the core commands — this checklist covers everything around them.

When Not to Use Nginx

Nginx is the right default, but not the only answer. For pure static sites, a CDN or object storage fronted by a CDN is simpler and cheaper than a server you maintain. For containerised apps behind an orchestrator, an ingress controller or service mesh may already terminate TLS. For local development, your framework's dev server is enough — nginx adds nothing until you need production concerns like TLS termination, caching or rate limiting. Choose nginx when you need a robust, boring edge: TLS, static files, buffering and proxying in one battle-tested binary.

Caching Static Assets

Once your server block works, make it fast. Add expires headers for images, CSS and JS so browsers cache them — a location block matching static extensions with expires 30d cuts repeat-visit load dramatically. Enable gzip (or brotli) for text assets — a few lines that typically shrink HTML, CSS and JS by 60–70%. For high-traffic sites, proxy_cache in front of your app can absorb huge spikes. These three — expires, compression, caching — are the highest-leverage performance wins in nginx, and they all live in the same server block you just generated.

Rate Limiting in a Few Lines

Once your proxy serves traffic, protect it. Nginx rate limiting needs two directives: one defines a shared memory zone keyed by client address, and the other applies that zone inside your location block. A modest per-second allowance with a small burst absorbs normal browsing while blunting scrapers and brute-force login attempts. Start permissive and tighten based on what the access logs show — an over-aggressive limit locks out real users behind shared office addresses, which is worse than the bots you were trying to stop.

Frequently asked questions

What is an nginx server block?

A server block (the server { ... } section) defines how nginx handles requests for one or more domain names: which port to listen on, where files live, and how locations are routed.

How do I reverse proxy to a Node.js app with nginx?

Use proxy_pass to forward requests to your app, e.g. proxy_pass http://localhost:3000;. Also set proxy_set_header Host $host and X-Real-IP so your app sees the real hostname and client IP.

How do I serve a static site or SPA with nginx?

Serve static files with root + try_files $uri $uri/ =404;. For single-page apps use try_files $uri $uri/ /index.html; so client-side routes do not 404 on refresh.

How does nginx work with PHP?

PHP runs in PHP-FPM, a separate process. Nginx forwards .php requests to it via fastcgi_pass unix:/var/run/php/php8.2-fpm.sock; inside a location ~ \.php$ block, with try_files $uri =404; for security.

How do I test and reload nginx config safely?

Run nginx -t to test syntax, then systemctl reload nginx to apply changes without dropping connections. Never reload without testing first.

What causes nginx 502 Bad Gateway?

A 502 means nginx is running but the upstream is not — your app process is down, the PHP-FPM socket path is wrong, or the port in proxy_pass does not match. Check the upstream first, not nginx.