A commented nginx server block for a reverse proxy, static site, SPA or redirect
Runs in your browser. Nothing you type is sent anywhere. Checked against sources on 22 Oct 2026.Pick what nginx should do, a reverse proxy, a static site, a single-page app or a domain redirect, type your domain, and get a complete commented configuration with HTTPS, HTTP/2, gzip, caching and security headers. It follows nginx 1.25.1 and later by default, with the older HTTP/2 form one switch away.
Pick what the server does: reverse proxy, static site, single-page app or redirect domain.
Type your domain and the app address, site folder or new address, and choose the main name.
Turn HTTPS, HTTP/2, gzip, caching and security headers on or off, and set your nginx version.
Copy or download the file, save it in /etc/nginx/sites-available, run sudo nginx -t, then reload nginx.
Most nginx configurations are copied from an answer written for another version and another job. This generator writes the whole file for yours, with a comment on every block, and leaves out the mistakes that are easy to copy.
Four starting points.
| Preset | What it writes |
|---|---|
| Reverse proxy | proxy_pass to your app with Host, X-Real-IP and X-Forwarded headers, an upload limit, optional WebSocket upgrades |
| Static site | root and index, try_files with a real 404, assets cached for 30 days |
| Single-page app | every route to index.html, index.html never cached, hashed assets cached for a year |
| Redirect domain | every address of the old domain to the new one in one hop, path kept or dropped |
HTTPS done properly. With HTTPS on, plain HTTP is sent to HTTPS on the main name, the www or bare name you do not use is sent to the one you do, and Let's Encrypt renewals keep working over HTTP. TLS is limited to versions 1.2 and 1.3 with Mozilla's intermediate session settings.
The nginx traps it avoids. An add_header inside a location silently drops every header of the server block, so the security headers are written once and caching uses expires instead. text/html is always compressed, so listing it in gzip_types only adds a warning. HTTP/2 is switched on with http2 on in nginx 1.25.1 and later; turn off the version switch for the older listen form.
The security headers come from the same rules as the security headers generator on this site: nosniff, a referrer policy, framing limited to your own site and HSTS only over HTTPS. Nothing you type is sent anywhere. Check the file with sudo nginx -t before reloading. Related tools: Security Headers Generator, .htaccess Redirect Generator, htpasswd Generator.
On Debian and Ubuntu, save it as /etc/nginx/sites-available/example.com.conf and link it into sites-enabled. On other systems, save it in /etc/nginx/conf.d/. Then run sudo nginx -t to check the syntax and sudo systemctl reload nginx to apply it without dropping connections.
Choose Reverse proxy, type your domain and the address the app listens on, such as http://127.0.0.1:3000. The config forwards every request with the Host and X-Forwarded headers, so the app sees the real domain, visitor address and https. Turn on WebSocket if the app uses them.
Nginx looks for a file matching the address, such as /settings, and finds none. The Single-page app preset adds try_files $uri $uri/ /index.html, which serves index.html for every path that is not a real file, so the app's router can show the right page.
From nginx 1.25.1, HTTP/2 is switched on with the separate http2 on directive, and the old listen parameter logs a deprecation warning. Run nginx -v to see your version, and turn off the 1.25.1 switch here if yours is older, such as 1.18 on Ubuntu 22.04.
In nginx, an add_header inside a location block replaces every add_header from the server block, it does not add to them. That is why this config writes the headers once at server level and uses the expires directive for caching, which sets Cache-Control without add_header.
Yes, nginx will not start with a missing certificate file. Load only the HTTP server block first, run certbot certonly --webroot -w /var/www/letsencrypt with your domain, then add the HTTPS blocks. The default paths are the ones certbot writes under /etc/letsencrypt/live.
Rates and rules change; check the source before you rely on a figure.
Still stuck? Ask about Nginx Config Generator and anybody who knows can answer. No account needed.
Same job, other tools: Disallow All Robots.txt – The two-line file that closes a staging site to crawlers · Block AI Crawlers – Keep model crawlers out while search crawlers carry on · Sitemap Index Generator – Split a large site into numbered sitemaps with an index file.
On the related tools: Cron Expression Generator – Generate a cron expression by choosing when the job should run.