Practical tools for system, network, security, and operations administrators.

SYS-C0717 · Web Server Guides

Nginx Configuration Guide

Serve one Nginx site on loopback, test the config, and reload only after nginx -t passes.

Updated 25 October 2026 · Pillar guide

This is an original planning guide. It is not a vendor manual, an official standard, or legal advice. Example addresses use documentation ranges. Review every command before you paste it.

Where Nginx sits

Nginx uses a configuration of contexts: events, http, server, location. A server block is a site. The test is nginx -t. The reload is the service reload, and only after the test passes. A failed test means you do not reload.

Debian and Ubuntu packages often add sites-available and a symlink in sites-enabled. Upstream Nginx and many other packages use conf.d. Look at the include lines in nginx.conf before you invent a third layout. The file you edit must be one that the include actually reads.

The lab listens on 127.0.0.1:8080 and serves a single test page from a directory the worker can read and not write. The web administration guide is the decision. This page is the Nginx file.

proxy_pass sends a location to an upstream you run. The upstream is an address in the ticket, not a hostname you have not resolved. You do not proxy to the public internet to see if the directive works.

A loopback site you can fetch

Step 1 for Nginx is the include. Read the include lines in nginx.conf and choose the file those lines load. A perfect server block in the wrong folder is not loaded. Check: nginx -T shows your server block. If the check fails, do not reload again and do not point a name at this host. Restore the previous file. The generators for Nginx draft a site in the browser and do not open a firewall. Delete every listen-on-every-address line for the lab. Replace prompt-for-this. A config from a neighbouring web server is not this syntax.

Step 2 for Nginx is the lab listener. Bind 127.0.0.1:8080 to a root with one test page. Loopback proves the config without a public firewall change. Check: A fetch from the host returns the page. If the check fails, do not reload again and do not point a name at this host. Restore the previous file. The generators for Nginx draft a site in the browser and do not open a firewall. Delete every listen-on-every-address line for the lab. Replace prompt-for-this. A config from a neighbouring web server is not this syntax.

Step 3 for Nginx is the test. Run nginx -t. Read the error if it fails. Reload of a bad file drops the sites that were working. Check: The test says syntax is ok before you reload. If the check fails, do not reload again and do not point a name at this host. Restore the previous file. The generators for Nginx draft a site in the browser and do not open a firewall. Delete every listen-on-every-address line for the lab. Replace prompt-for-this. A config from a neighbouring web server is not this syntax.

Step 4 for Nginx is the worker. Confirm the user directive and the directory mode. A worker that can write the site can be abused if the site is later public. Check: The worker reads the file and the directory is not writable by that user. If the check fails, do not reload again and do not point a name at this host. Restore the previous file. The generators for Nginx draft a site in the browser and do not open a firewall. Delete every listen-on-every-address line for the lab. Replace prompt-for-this. A config from a neighbouring web server is not this syntax.

Step 5 for Nginx is proxy only if named. Add proxy_pass only if the ticket names an upstream, and test that upstream first. An upstream that is down looks like an Nginx bug. Check: The upstream answers, then the proxied location answers. If the check fails, do not reload again and do not point a name at this host. Restore the previous file. The generators for Nginx draft a site in the browser and do not open a firewall. Delete every listen-on-every-address line for the lab. Replace prompt-for-this. A config from a neighbouring web server is not this syntax.

# Nginx lab. Review before you paste.
# listen 127.0.0.1:8080;
# root is a directory of one test page.
# nginx -t && then reload.
# Do not listen on every address in the lab.
# proxy_pass only to an upstream you run.

Certificates come after the name is yours

TLS is a server block you add when the name is yours and DNS points here, or when you are still on loopback with a certificate you generated for the lab and do not ship. ssl_certificate and ssl_certificate_key point at files. The key is not world-readable and not in the ticket.

Old protocols stay off. Do not paste a sample that enables ancient TLS for compatibility you have not measured. The defaults on a current Nginx are the starting point. You read them.

A reload after the certificate change still follows nginx -t. A certificate path that does not exist fails the test, which is what you want.

What not to paste

Nginx is not Apache. A VirtualHost and a .htaccess file do not belong in nginx.conf. The migration converters draft a translation. They do not skip the test.

sites-available is not universal. Do not create that directory on a host whose nginx.conf never includes it.

Listening on every address in the lab is not required to prove the site works.

The hour you stop

Write the hostname, the role, and the clock time before you change Nginx. If this host is also serving users, it is not the lab and this first hour belongs on a spare. The provisioning guide is how the spare gets built. A change without a spare is a change you can still postpone.

Keep the console or the out-of-band path open for the whole hour. Reloading a network service, a firewall, or a secure-shell daemon from the only session is how a lab becomes a drive across town. The hardware guide names that path for a physical machine. A virtual machine uses the hypervisor console. A cloud instance uses the serial console the platform gives you. Test it before the reload, not after.

The address 192.0.2.10/24 and the gateway 192.0.2.1 are documentation. They belong in the lab note and nowhere else. On a real network, use the prefix the network desk already assigned. On a cloud instance, use the address the platform assigned and do not hard-code the documentation range into user-data. If a generator filled the documentation address into a production draft, delete it.

prompt-for-this is a reminder that a secret is missing. It is not a password you set, not a token you commit, and not a string you leave in a configuration file because the service started. The real secret lives in the password store. The ticket says who can read it. A file that still contains the reminder is a file you have not finished.

One service is enough for the first hour on Nginx. The purpose from the fundamentals page says which service. Every other package stays uninstalled until its own guide has a ticket. A host that enables a web server, a database, and a queue in the first hour has three changes and no proof. Finish the login, the address, and the update. Then stop.

Read the package transaction before you accept it. A count of packages is not a review. If the list contains a repository you did not add, stop. If it contains a kernel, the patch guide's reboot decision applies and the console stays open. If it contains software this role does not need, remove that line from the plan rather than installing it and disabling it later.

The previous image, the previous configuration file, or the previous package version is the rollback. Write the path down while the host still works. A rollback you invent after a failed reload is a guess. The migration guide assumes the old copy is still there. Do not delete it in the same hour to free a disk.

When the checks pass, copy the notes into the ticket and leave the host alone. The next host waits until a second person can repeat the login and the address from the notes. A fleet built from memory drifts. A fleet built from the file the provisioning guide stored stays boring, which is the point of Nginx in production.

If a step on Nginx fails twice, stop for the day. The failure is the result. Adding a forum command beside a half-applied config produces a host nobody can rebuild. Rebuild from the image instead. The time you lose is smaller than the time you will spend explaining the hybrid.

Hand the finished lab to the guide that matches the role: web, mail, storage, backup, or hardening. Nginx being installed is not the same as the role being ready. The role guide has its own proof. Do not skip it because the package manager exited without an error.

A second person reads the hostname, the address, and the rollback path aloud before you build the next host. If they cannot find those three in the ticket, the notes are not done. Silence is not agreement. The check is the sentence they repeat back.

Store the working notes next to the image version. A month from now Nginx will still boot from that pair, and the chat where you remembered a flag will be gone. The file is the memory. The host is replaceable. That is the whole point of writing this hour down.

Nginx checks before a public listener

Confirm this before you call the change done: Nginx is the process that is listening, confirmed on the host. The lab site binds to 127.0.0.1, not to every address. The config test passed before the reload. A fetch of the test page from the host itself succeeded. The admin or dashboard port is not reachable from a public address. The document root is readable by the worker and not writable by it. No certificate was requested for a name you do not control. The generator draft was edited until it matched this file. The previous config is saved. prompt-for-this was not left in a password field. Logs from the test do not contain a secret. A second person read the listen address. nginx -T shows the listen address you intended. sites-enabled was used only if nginx.conf includes it. No Apache directive remains in the file. And the key file, if any, is not in the ticket. If one of those fails, stop.

Tools for this guide

These tools run in the browser on this site. They do not log into your machines.

Guides in this cluster

These supporting pages belong to this pillar.