Loading...

About the Nginx Directives cheat sheet

Nginx configuration is powerful and unforgiving because directive behaviour depends on the block it sits in and on a location matching order that is not the order written in the file. Two configurations that look equivalent can behave completely differently.

Location matching is the part worth learning properly. Exact matches win first, then prefix matches marked to stop regex evaluation, then regular expressions in file order, then the longest ordinary prefix match. Assuming top-to-bottom evaluation is the most common source of a request reaching the wrong block.

The other recurring issue is proxy headers. Nginx does not forward the original host or client address to an upstream by default, so applications behind it see the proxy rather than the client, and generate redirects pointing at the internal name unless the headers are set explicitly.

Frequently asked questions

Why is the wrong location block handling my request?

Because matching is by specificity and type, not file order. Exact matches are considered first, then prefix matches that suppress regex checking, then regexes in the order they appear, then the longest plain prefix. A regex earlier in the file can capture a request you expected a later prefix block to handle.

What is the difference between proxy_pass with and without a trailing slash?

It changes what URI the upstream receives. With a trailing slash, the part of the request matched by the location prefix is stripped before forwarding. Without one, the full original URI is passed through. This single character accounts for a large share of unexpected 404s from an upstream.

Which headers should I set when proxying?

Host, so the upstream generates correct absolute URLs; X-Real-IP and X-Forwarded-For, so it can log and rate-limit the real client; and X-Forwarded-Proto, so it knows the original request was HTTPS. Without the last one an application will often redirect an HTTPS request to HTTP and create a redirect loop.

How do I serve a maintenance page without downtime?

Use a conditional return based on the existence of a flag file, so enabling maintenance is creating a file rather than editing and reloading the config. Return 503 with a Retry-After header so crawlers understand it is temporary, and exclude health check paths so your load balancer does not mark the node dead.

Why do my changes not take effect after a reload?

Test the configuration first — nginx keeps running the old config if the new one fails to parse, and the failure is easy to miss. If it parses cleanly, check whether another server block matches the hostname first, since the default server handles anything unmatched. Browser and CDN caching accounts for most of the rest.

Need this managed for you, not just automated?

We're also a hands-on DevOps consultancy — Kubernetes, CI/CD, and cloud infrastructure.

Explore Our Services