Nginx config generator
Produce a sensible, secure Nginx server block for a site or reverse proxy.
Have feedback or an idea for this tool?
What is an Nginx server block?
An Nginx server block is the configuration that tells the Nginx web server how to handle requests for a particular site or domain: which name and port to listen on, where files live, and how to pass traffic to an application. This tool generates a sensible, secure block for a static site or a reverse proxy, including HTTPS redirection, sensible headers and a proxy_pass to your app port, so you start from a working baseline rather than a blank file. Enter your domain and options to produce the config. A good server block also handles the ACME challenge for certificates and forwards the real client address to your application. Use the output as the basis for a new virtual host, adjusting paths and upstreams for your setup, then test it with nginx -t before reloading the server.
Key facts
- Nginx serves each site from a server block whose listen and server_name directives decide which block handles a request.
- A reverse proxy passes requests to an app with proxy_pass, and proxy_set_header lines are needed so the app sees the real client IP and scheme.
- An HTTPS server block uses listen 443 ssl with ssl_certificate and ssl_certificate_key, and the fullchain file should include the leaf plus intermediate certificates.
- A plain HTTP to HTTPS redirect is done with a listen 80 block that returns 301 https://$host$request_uri.
- Nginx does not obtain TLS certificates itself; it only reads the certificate files you point it at, which are typically issued by Certbot or acme.sh.
The anatomy of an nginx server block
Nginx serves each site from a 'server' block inside the http context. The two directives that decide which block handles a request are 'listen' and 'server_name'. 'listen 80;' handles plain HTTP and 'listen 443 ssl;' handles HTTPS; 'server_name example.com www.example.com;' matches the Host header. A request that matches no server_name falls through to the default_server block.
Inside the block you either serve files or hand the request off. 'root /var/www/example;' sets the directory that files are served from, and 'index index.html;' names the default file for a directory. To hand the request to another process instead you use 'proxy_pass' (for an app or upstream) or 'fastcgi_pass' (for PHP-FPM) inside a 'location' block - root and proxy_pass are mutually exclusive per location.
'location' blocks route by URI path or regex. 'location / { ... }' is the catch-all; 'location /api/ { ... }' matches a prefix; 'location ~ \.php$ { ... }' matches a regex. Nginx picks the most specific match, so a static-file location and a proxy location can coexist in one server block.
nginx: server block (ngx_http_core_module) · nginx: how location is chosen
Reverse proxy to an app on a port
The most common setup is putting nginx in front of an app (Node, Django, Rails, a Go binary) that listens on a local port such as 127.0.0.1:3000. Nginx terminates the public connection and forwards the request to the app. A minimal proxy location looks like this: 'location / { proxy_pass http://127.0.0.1:3000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; }'.
The proxy_set_header lines matter: without them the app sees nginx's address instead of the real client, and cannot tell HTTP from HTTPS. For WebSockets, also add 'proxy_http_version 1.1;', 'proxy_set_header Upgrade $http_upgrade;' and 'proxy_set_header Connection "upgrade";'. Bind the app to 127.0.0.1, not 0.0.0.0, so only nginx can reach it.
For several backends you can define an 'upstream' block with multiple 'server' lines and proxy_pass to it by name, which gives you basic load balancing across app instances.
SSL/TLS and the HTTP to HTTPS redirect
To serve HTTPS, the server block listens on 443 with the ssl flag and points to your certificate and key: 'listen 443 ssl;', 'ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;', 'ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;'. Use the fullchain file (leaf plus intermediates) so clients that do not cache intermediates still trust the chain.
Send plain HTTP to HTTPS with a small dedicated block: 'server { listen 80; server_name example.com; return 301 https://$host$request_uri; }'. A 301 return is cheaper and cleaner than an if/rewrite. Restrict protocols to 'ssl_protocols TLSv1.2 TLSv1.3;' and let nginx pick a modern cipher set; the Mozilla SSL Configuration Generator is the standard source for a hardened block.
Nginx does not obtain certificates - it only reads the files you point it at. Get a free certificate with Certbot or acme.sh (Let's Encrypt), then reference the issued paths. Certbot can also edit the config for you, but the generator here writes the directives so you can paste them in yourself.
nginx: configuring HTTPS servers · Mozilla SSL Configuration Generator
Static sites, PHP-FPM, gzip and where the file lives
A static site needs only a root and a fallback: 'root /var/www/site;' plus 'location / { try_files $uri $uri/ =404; }' (single-page apps use 'try_files $uri $uri/ /index.html;' so client-side routes resolve). A PHP site adds a location that passes .php requests to PHP-FPM over a socket: 'location ~ \.php$ { include fastcgi_params; fastcgi_pass unix:/run/php/php8.3-fpm.sock; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; }'.
Turn on compression once, globally or per server, to cut transfer size: 'gzip on; gzip_types text/css application/javascript application/json image/svg+xml; gzip_min_length 1024;'. HTML is compressed by default, so it is not listed. There is no point gzipping already-compressed formats like JPEG or PNG.
On Debian and Ubuntu the file goes in /etc/nginx/sites-available/ and is symlinked into /etc/nginx/sites-enabled/; on RHEL, CentOS and Alma it goes in /etc/nginx/conf.d/ with a .conf suffix. After copying it in, always validate before reloading (see the steps below).
Glossary
- Server block
- A server block is the nginx configuration unit that defines one virtual host inside the http context. Its listen and server_name directives decide which block handles an incoming request.
- listen and server_name
- The listen directive sets the port and flags, such as listen 80 for HTTP or listen 443 ssl for HTTPS, while server_name matches the request's Host header to select the block.
- Location block
- A location block routes requests by URI path or regex within a server block. Nginx picks the most specific match, so a static-file location and a proxy location can coexist in one server block.
- Reverse proxy (proxy_pass)
- A reverse proxy forwards requests to a backend app with proxy_pass, for example proxy_pass http://127.0.0.1:3000. proxy_set_header lines are needed so the app sees the real client IP and scheme.
- root vs proxy_pass
- root serves files directly from a directory on disk for static content, while proxy_pass hands the request to another process and returns its response. They are mutually exclusive within a single location.
- SSL directives
- An HTTPS server block uses listen 443 ssl with ssl_certificate and ssl_certificate_key pointing at the certificate files. The fullchain file should include the leaf plus intermediate certificates.
Questions, answered.
How do I set up nginx as a reverse proxy?+
Put a proxy_pass in the location block that points at your app's local address, for example 'location / { proxy_pass http://127.0.0.1:3000; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; }'. Bind the app to 127.0.0.1 so only nginx can reach it, then run 'nginx -t' and reload.
What is the difference between root and proxy_pass?+
'root' tells nginx to serve files straight from a directory on disk - use it for static sites and assets. 'proxy_pass' hands the request to another process, such as an app on a port or an upstream, and returns its response. They are mutually exclusive within one location: a location either serves files or proxies, not both.
How do I add SSL and force HTTPS in nginx?+
In the HTTPS block use 'listen 443 ssl;' with 'ssl_certificate' pointing at your fullchain.pem and 'ssl_certificate_key' at your privkey.pem. Then add a separate port 80 block that redirects: 'server { listen 80; server_name example.com; return 301 https://$host$request_uri; }'. Nginx reads the certificate files but does not issue them - get one from Let's Encrypt with Certbot or acme.sh.
How do I configure PHP with nginx?+
Nginx does not run PHP itself; it passes .php requests to PHP-FPM. Add 'location ~ \.php$ { include fastcgi_params; fastcgi_pass unix:/run/php/php8.3-fpm.sock; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; }' and set the server's 'root' to your web directory. Confirm the FPM socket path matches your installed PHP version.
What does 'nginx -t' do and how do I apply a config?+
'nginx -t' parses your configuration and checks the syntax and referenced file paths without touching the running server; it prints 'test is successful' when the config is valid. Only after that, apply the change with 'systemctl reload nginx' or 'nginx -s reload', which reloads gracefully without dropping live connections. Never reload before the test passes.
Where do I put the nginx config file?+
On Debian and Ubuntu, save it in /etc/nginx/sites-available/ and symlink it into /etc/nginx/sites-enabled/. On RHEL, CentOS and Alma, place a .conf file in /etc/nginx/conf.d/. Both are pulled in by the main /etc/nginx/nginx.conf via an include, so the server block loads on the next test and reload.
How do I turn on gzip compression?+
Add 'gzip on;' and list the types to compress, for example 'gzip_types text/css application/javascript application/json image/svg+xml;', plus 'gzip_min_length 1024;' to skip tiny responses. HTML is compressed by default so it need not be listed. Do not gzip already-compressed formats like JPEG, PNG or WebP - it wastes CPU for no gain.
Is anything I enter in the generator sent to a server?+
No. The config is built entirely in your browser, so the domain names, ports and upstream addresses you type stay on your machine. You copy the finished server block and paste it onto your own server.
Cloud that speaks India.
These tools run on ServerCake infrastructure in India. When our cloud opens, you get VMs and managed databases priced in ₹, billed with GST, on India-resident infrastructure. Reserve your spot for early access.
Reserve your spot