Guide
Nginx server blocks for reverse proxies, single-page apps and PHP
Nginx sits in front of a great many web applications: it terminates HTTPS, serves static files quickly and forwards everything else to an app server. Its configuration language is compact but full of details that matter, from redirect loops to missing proxy headers. This generator writes a complete server block for the four most common setups.
How a server block is organised
Each site is a server { } block that says which addresses and names it answers (listen and server_name) and what to do with requests, usually through location blocks. A typical HTTPS site actually needs several blocks: one on port 80 that redirects to HTTPS, one for the www or bare variant that redirects to the preferred name, and the main one on port 443. The generator writes all of them in the right order.
Four site modes
Reverse proxy mode forwards every request to an app server such as http://127.0.0.1:3000 with proxy_pass, adding the Host, X-Real-IP, X-Forwarded-For and X-Forwarded-Proto headers so the app knows the original host, client and scheme. Static mode serves files from a root folder. Single-page app mode adds try_files $uri $uri/ /index.html, so deep links in React, Vue or Svelte apps load the app instead of a 404. PHP mode passes .php requests to PHP-FPM over its socket.
HTTPS and www redirects
With HTTPS on, the port 80 block answers Let’s Encrypt’s HTTP challenges from /.well-known/acme-challenge/ and redirects everything else with a 301 to HTTPS. The main block listens on 443 with ssl and http2 on, the syntax for Nginx 1.25.1 and later, points at the certificate and key, allows only TLS 1.2 and 1.3 and enables a session cache. Choose whether www. should redirect to the bare domain, the other way round, or serve both.
WebSockets, compression and caching
For apps with live updates, the WebSocket option adds proxy_http_version 1.1 and the Upgrade and Connection headers that let a connection switch protocols, with a long read timeout so idle sockets stay open. Gzip compresses text types above 1 KB. In static and SPA modes, long-lived caching headers for CSS, JavaScript, fonts and images let browsers keep fingerprinted assets for 30 days.
Security headers
The security option adds X-Content-Type-Options: nosniff, X-Frame-Options: SAMEORIGIN and Referrer-Policy: strict-origin-when-cross-origin, plus Strict-Transport-Security with a one-year max-age when HTTPS is on. A Content-Security-Policy is deliberately left out, because a wrong one breaks a site; build it for your pages with the CSP Hash Generator.
A worked example
With the defaults, the first block listens on port 80 for both names and returns return 301 https://example.com$request_uri;. A second block on 443 sends www.example.com to the bare domain. The main block proxies to proxy_pass http://127.0.0.1:3000; with the forwarding headers and proxy_set_header Upgrade $http_upgrade;, enables http2 on;, gzip and the security headers, and accepts uploads up to 20 MB. Switching to single-page app mode replaces the proxy location with try_files $uri $uri/ /index.html;.
Testing and enabling
Save the file under /etc/nginx/sites-available/, link it into sites-enabled, then always run sudo nginx -t before sudo systemctl reload nginx; the test catches syntax errors without taking the running server down. Obtain the certificate first with certbot’s webroot mode, or start without HTTPS and add it after.
Related tools
- Redirect Generator adds page-level redirects to the server block.
- systemd Unit Generator keeps the app behind the proxy running.
- Firewall Rule Generator opens ports 80 and 443 only.
- CSP Hash Generator builds a Content-Security-Policy for the site.
Checked against the current version of the Nginx Config Generator on .

