Your site
Leave empty to use the suggestion. For Laravel it must be the public folder.
The socket path on Debian and Ubuntu. Use 127.0.0.1:9000 for a TCP pool or app:9000 for a container.
Where the app listens, such as a Node.js server or a Docker container published on 127.0.0.1.
HTTPS and options
Nginx’s own default is 1M. Match PHP’s upload_max_filesize.
Your config
Put it in place
How to use the Nginx config generator
- Choose what runs on the site and enter its domain. The document root and PHP-FPM socket are filled in with the usual Ubuntu paths; change them if yours differ.
- Pick the options you want. The defaults are a sensible production setup: HTTPS with a redirect from HTTP, the www name redirected to one address, compression, browser caching for static files and basic security headers.
- Copy the config, then run the commands below it: get the certificate, save the file, test it with
nginx -tand reload Nginx.
Everything is built in your browser. Nothing you type is sent to Cloudhim.
What the generated config does
- One canonical address. Requests to plain HTTP and to the other www variant get a 301 redirect to a single HTTPS address, which is what search engines and browsers expect.
- PHP the safe way. For Laravel, only
public/index.phpis ever executed, as in Laravel’s own deployment docs. For WordPress and other PHP apps, a PHP file runs only if it exists on disk (try_files $uri =404), and PHP in the uploads folder is blocked. - Hidden files blocked.
.env,.gitand other dot files return 403, while/.well-known/stays reachable for Let’s Encrypt. - Reverse proxy headers. The app receives the visitor’s IP and the original scheme in
X-Forwarded-ForandX-Forwarded-Proto, and WebSocket connections are upgraded when you allow them.
Getting the HTTPS certificate
The config points at the files Certbot creates in /etc/letsencrypt/live/, so the certificate has to exist before nginx -t will pass. Run the certbot certonly --nginx command shown above first: it needs the domain’s DNS pointing at the server and port 80 open. Certbot renews the certificate automatically, and the --deploy-hook in the command reloads Nginx after each renewal so it uses the new certificate. If Certbot can’t complete the check, generate the config with HTTPS turned off, enable it, run sudo certbot --nginx, then switch to the HTTPS version.
HTTP/2 and Nginx versions
Nginx 1.25.1 changed how HTTP/2 is switched on, from listen 443 ssl http2 to a separate http2 on; line. The old form still works on new versions but prints a warning, while the new form fails on older ones. Ubuntu 24.04 and Debian 12 ship older Nginx versions, so the generator uses the form that works everywhere unless you choose otherwise. Check yours with nginx -v.
Common problems
- 502 Bad Gateway: Nginx can’t reach PHP-FPM or the app. Check the socket path with
ls /run/php/, or, for a proxy, that the app listens on the address you entered. A proxy tolocalhostcan fail when the app only listens on IPv4; see Nginx 502 errors and localhost. - 413 Request Entity Too Large: the upload is bigger than
client_max_body_size. Raise it here and PHP’supload_max_filesizeandpost_max_sizetogether. - Too many redirects: usually WordPress or the app thinks it’s on HTTP while Nginx redirects to HTTPS. Set the site address to https:// in the app, and behind Cloudflare use SSL mode Full (strict).
- “duplicate map”: the WebSocket
mapmay exist only once across all sites. Delete the copy from the newer file.
Moving from Apache? Convert your rules with the .htaccess to Nginx Converter, then check the headers you send with the Security Headers Checker.