- Host multiple websites on a single server using
server_name. - Perform redirects with
return(for simple canonicalization like HTTP → HTTPS). - Rewrite URLs with
rewriteusing regular expressions and capture groups. - Define
upstreampools and apply load balancing (round-robin, weighted, least connections, IP hashing). - Use NGINX as a reverse proxy to forward requests to backend services on other ports.
- Enable caching to improve performance and reduce backend load.

Quick overview
Below is a short table summarizing the topics and their typical use cases:Hosting multiple sites on one server (server_name)
NGINX matches requests to a particular server block by listening port andserver_name. Use separate server {} blocks for each domain or subdomain.
Example: two sites on the same IP, one for example.com and one for api.example.com:
- The order of
server_namematching: exact names, longest wildcard starting with*, longest wildcard ending with*, then regex. - Use
listen 443 ssl;and certificate directives in the HTTPS server block.
When you add a new domain, create a dedicated
server block and test the config using nginx -t before reloading with systemctl reload nginx (or nginx -s reload).Redirects using return
For straightforward redirects (for example redirecting all HTTP traffic to HTTPS or canonicalizing www), prefer return because it’s simpler and faster than rewrite.
HTTP → HTTPS redirect example:
www to non-www:
301 for permanent redirects and 302 for temporary ones.
Avoid using
rewrite when a simple return covers your use case—return is easier to read and slightly more efficient.Rewriting URLs with rewrite and regex
rewrite allows transforming requested URIs using PCRE regular expressions and capture groups. Use it when you need complex mapping (e.g., legacy URL structures -> friendly URLs).
Example: redirect old article paths to a new structure:
^/old/([0-9]{4})/([0-9]{2})/(.*)$captures year, month, and slug.$1,$2,$3reference the captured groups.permanentissues a 301 redirect.
- Test your regex with tools like regex101 to avoid accidental matches.
- Order matters: exact
locationblocks are evaluated before regexlocationblocks. Place regexlocationblocks carefully.
Upstream pools and load balancing
Useupstream blocks to define backend server groups. Reference the group from proxy_pass or other proxy directives.
Basic upstream with round-robin (default):
Reverse proxy essentials
When proxying, ensure headers and client IPs are passed correctly. The typical minimal proxy configuration includes:proxy_http_version 1.1and clearingConnectionheader help with keepalive behavior to upstreams.- If your backend runs on a different port, include it in the upstream server definition (e.g.,
server 127.0.0.1:3000;).
Caching responses with proxy_cache
Caching reduces backend load and improves response times. A simple caching setup:
keys_zonereserves memory for cache keys (e.g.,10m).proxy_cache_validsets caching durations by status code.X-Proxy-Cacheheader helps verify whether a response was served from cache (HIT) or passed to the backend (MISS).
Design cache keys carefully (including query strings or authentication headers when needed) and have a strategy for cache invalidation. For advanced cache purging, consider modules like
ngx_cache_purge or manage via short TTLs and revalidation.Final notes and best practices
- Always test configuration changes with
nginx -tand monitor error logs at/var/log/nginx/error.log. - Keep redirect and rewrite rules simple and clearly documented to avoid surprise behavior.
- Use health checks and proper monitoring for upstream backends to detect failures quickly.
- Use HTTPS and HSTS in production; consider automating certificate management with Let’s Encrypt (Certbot) or similar tools.
Links and references
- NGINX Documentation — Module ngx_http_core_module
- NGINX Docs — Reverse Proxy
- NGINX Guide — Load Balancing