October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsPC HealthRecommendedCrashes, freezes, slowdowns? Check your PC nowSpot repairable issues before they interrupt work.Check PCOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
VGSources
Blog

How to Set Up a Reverse Proxy for a WordPress Site with NGINX

A practical guide to placing NGINX in front of WordPress: configure proxy_pass, preserve Host and client headers, prevent HTTPS loops, align URLs, validate admin and media paths, and add safe caching.
Length12 min Posted Quest giverVGSources Team
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Put NGINX at the public edge, keep WordPress on an origin server, and forward each request with proxy_pass. The reliable setup preserves the public Host, sends the client and scheme headers WordPress needs, tells WordPress when the original request used HTTPS, and keeps every canonical URL on the same public hostname. Build and test the basic proxy first; add page caching only after redirects, cookies, administration, media, uploads, and APIs work normally.

What the reverse-proxy layout does

A reverse proxy is the server visitors contact. NGINX accepts the browser connection, terminates TLS when configured to do so, and forwards the request to a private WordPress origin. The origin can run Apache or NGINX with PHP. The browser never needs to know the origin address.

As an Amazon Associate I earn from qualifying purchases.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Browser → TLS/NGINX reverse proxy → WordPress origin (Apache or NGINX/PHP)

WordPress remains the application and content origin; NGINX is the public traffic layer. This arrangement lets an Apache-based WordPress installation use NGINX for the public connection while retaining Apache’s application features. It also gives you one place to manage certificates, forwarded identity, redirects, access control, and (if you later choose it) caching.

Decisions to make before editing configuration

Decision Option A Option B Why it matters
TLS termination NGINX terminates HTTPS The origin also receives HTTPS When NGINX terminates TLS and forwards HTTP, WordPress must be told that the original request was secure.
Proxy-to-origin transport HTTP HTTPS The upstream protocol in proxy_pass must match the service actually listening on the origin.
Origin web server Apache NGINX/PHP Both can serve WordPress behind the public NGINX layer.
Cache scope Static assets only HTML and application responses with exclusions Authenticated, administrative, POST, and personalized responses must not be shared between visitors.

Where possible, firewall the origin so it accepts web traffic only from the proxy. Before introducing the edge, verify that the origin responds correctly for its intended host and path. This isolates application problems from proxy problems.

Compare deployment patterns

There is no single best topology. A standalone NGINX origin is straightforward when you want one web server, while NGINX in front of Apache is useful when an existing Apache configuration, module, or application workflow is already working. In either pattern, document where TLS terminates, whether the internal hop uses HTTP or HTTPS, and which layer owns redirects. If another load balancer or CDN sits in front of NGINX, decide which layer writes each forwarded header and make the public edge overwrite untrusted incoming values.

Operational support is another distinction. A self-managed pair of servers requires you to maintain certificates, firewall rules, upstream health, logs, and rollback procedures. A managed WordPress host may provide configurable edge proxying and support, while a commercial NGINX Plus deployment can add vendor support and enterprise features. Confirm current pricing and partner terms directly before making a purchasing decision.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Prepare the WordPress origin

Confirm the origin on its own

  1. Identify the origin address and listening port, such as wordpress_origin:8080.
  2. From the proxy host, request the origin directly and confirm that the homepage, a pretty permalink, media files, and the login page return expected responses.
  3. Check the origin’s web-server and PHP logs before changing DNS or public traffic.
  4. Restrict inbound access to the proxy network where your network design permits it. Keep an administrative path for direct troubleshooting that is not exposed publicly.

The origin should already know which WordPress files, PHP handler, uploads directory, and permalink rules it serves. A reverse proxy cannot repair an origin that fails when contacted directly. Check that the origin has enough PHP workers and database connectivity for normal requests; otherwise a proxy may only make the resulting timeout or error harder to diagnose.

Choose the public canonical URL

Decide whether visitors will use https://example.com or another single public hostname. Use that exact scheme and hostname in NGINX redirects, WordPress constants, and the database’s home and siteurl options. A mismatch is a common cause of wrong-domain redirects, mixed media URLs, and login loops.

Make a short inventory before cutover: the preferred hostname, any alternate hostname that should redirect, the HTTP and HTTPS listeners, the origin address and port, certificate paths, and the WordPress paths that must remain dynamic. This inventory gives you a rollback checklist and prevents an old DNS name or internal port from being copied into a public URL.

Create the public NGINX server block

Set the public server_name, listen on the ports you need, configure the certificate if NGINX terminates TLS, and route the site location to the origin. This minimal location contains the important forwarding behavior:

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
server {
    listen 443 ssl;
    server_name example.com;

    ssl_certificate /etc/ssl/example.com/fullchain.pem;
    ssl_certificate_key /etc/ssl/example.com/privkey.pem;

    location / {
        proxy_pass http://wordpress_origin:8080;
        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-Host $server_name;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_redirect off;
    }
}

proxy_pass sends the request to the upstream. Each proxy_set_header line changes or adds a request field before forwarding it. Replace the example certificate paths, hostname, and upstream address with the values used by your deployment; do not copy example paths unchanged into production.

If the origin uses HTTPS, change the upstream URL to an https:// address and configure the origin certificate verification policy deliberately. Do not assume that changing the protocol is harmless: a wrong scheme or port produces connection failures even when the WordPress application itself is healthy. Keep the location broad enough for normal WordPress paths, and add narrower locations only when you have a documented reason.

What each forwarded header is for

Header Value in the example Purpose
Host $host Preserves the public hostname so WordPress and the origin do not construct links for an internal address.
X-Real-IP $remote_addr Passes the connecting client address to the origin.
X-Forwarded-For $proxy_add_x_forwarded_for Maintains the forwarded client-address chain across proxy hops.
X-Forwarded-Host $server_name Identifies the public host selected by the NGINX server block.
X-Forwarded-Proto $scheme Tells the origin whether the browser connection reached NGINX over HTTP or HTTPS.

Only trust these headers when they are set or overwritten by a proxy you control. If clients can reach the origin directly, they may be able to spoof a forwarded scheme or address. Overwrite incoming values at the trusted edge and prevent bypass access with firewall rules. In a multi-proxy chain, document whether the application should trust the first or last address in X-Forwarded-For; do not treat an arbitrary client-supplied chain as authoritative.

Handle the HTTP listener deliberately

If HTTPS is your canonical scheme, configure the HTTP listener to redirect to the same public hostname and HTTPS path, or serve it according to your site’s policy. Ensure that only one layer performs the canonical redirect. A second proxy, load balancer, CDN, Apache rule, or WordPress plugin that makes a conflicting decision can create a loop.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Make WordPress detect HTTPS behind NGINX

When TLS ends at NGINX and the hop to the origin is HTTP, the origin itself sees an HTTP connection. WordPress therefore needs a trusted mapping from X-Forwarded-Proto to its HTTPS server variable. Add this handling in wp-config.php before WordPress finishes loading:

if ( isset($_SERVER['HTTP_X_FORWARDED_PROTO']) &&
     strpos($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') !== false ) {
    $_SERVER['HTTPS'] = 'on';
}

Adapt the condition to your trusted-header policy. The important safety rule is that the value must come from your controlled proxy, not from an untrusted direct request. If the origin itself receives HTTPS, or another trusted layer already sets the equivalent server variable, do not add competing logic without checking how those layers interact.

Why a missing scheme mapping causes a loop

The browser requests HTTPS. NGINX forwards the request over HTTP. WordPress sees HTTP and redirects to HTTPS. The browser follows the redirect back to NGINX, which repeats the same HTTP upstream request. WordPress again believes the request is insecure, so the cycle never ends. Forwarding X-Forwarded-Proto and mapping a trusted https value to $_SERVER['HTTPS'] lets WordPress recognize the original scheme and stop redirecting.

Align WordPress URLs with the public hostname

WordPress builds links, redirects, feed addresses, REST links, and many cookie decisions from its configured URL values. If you need constants in wp-config.php, use the public URL:

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
define('WP_HOME', 'https://example.com');
define('WP_SITEURL', 'https://example.com');

The constants, the database’s home and siteurl options, and the hostname visitors actually enter must agree. Do not set them to the origin’s private name, port, or HTTP scheme. Keep the public Host and X-Forwarded-Host consistent with that choice. WordPress derives HTTP_HOST from the request’s Host header, so an incorrect or attacker-controlled host can produce incorrect canonical URLs.

Keep redirects in one canonical direction

  • Choose one hostname, including whether the www form is used.
  • Choose one scheme, normally HTTPS for the public site.
  • Make NGINX, WordPress constants, database URL options, and any origin redirect rules point to that same result.
  • Remove or disable rules that redirect HTTPS back to HTTP or rewrite the public host to the internal origin name.

Validate the proxy before enabling cache

Run the NGINX configuration test supplied by your installation (commonly the nginx -t command), and reload only after it reports success. Then test through the public hostname, not just by connecting directly to the origin.

  1. Open the HTTPS homepage and confirm the address bar remains on the intended hostname.
  2. Open a pretty permalink and a page with images or other media.
  3. Visit /wp-admin/, sign in, navigate between administration screens, and sign out.
  4. Submit the login form again in a private browser session to check that authentication cookies survive the proxy.
  5. Request an upload and verify that the resulting media URL uses the public scheme and hostname.
  6. Call the REST API and any XML-RPC, webhook, payment, or callback endpoints your site uses.
  7. Submit a form or other POST request and confirm it reaches WordPress without being redirected unexpectedly.
  8. Inspect response headers and NGINX logs when a result differs between a direct-origin request and a public request.

Test both the bare and preferred hostname if you support a redirect between them. Also test from a network outside the proxy’s local environment; an internal DNS override can hide public DNS or firewall mistakes. Repeat a small smoke test after every certificate renewal, origin migration, WordPress URL change, or proxy configuration edit.

Add caching only as a separate change

A reverse proxy can operate correctly without caching. Treat HTML caching as a later change so a cache does not conceal a header, cookie, or redirect error. NGINX supports disk-based caching and purge controls, and WordPress-oriented configurations commonly use FastCGI caching with request and cookie exclusions.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Responses that must bypass shared HTML cache

  • Logged-in sessions and requests carrying authentication or account cookies.
  • /wp-admin/ and wp-login.php.
  • All POST requests, including comment submission and form handlers.
  • Carts, checkout, account pages, previews, and other transaction or personalization paths.
  • Any response that varies by user, cookie, authorization, location, or other private state.

Disable caching for these requests before creating cache objects, then purge objects already stored under those paths. A cache exclusion added after private content was stored does not remove the existing copies. Be especially careful with plugins that add cookies or personalize otherwise ordinary-looking pages; exclusion rules must follow the response’s behavior, not only its URL.

Define invalidation before publishing

Decide how a post edit, page update, menu change, theme change, or plugin update purges affected HTML. Without a purge strategy, visitors can continue receiving stale pages after WordPress has changed. Test a publish-and-refresh cycle from an unauthenticated browser before declaring caching ready. Record who can purge, how a full purge is requested, and what happens if the cache store is unavailable.

Use different lifetimes for assets and HTML

Static assets can generally have longer browser and edge lifetimes than generated HTML, provided filenames or another versioning method changes when content changes. Keep HTML lifetime and purge behavior conservative until you have measured freshness requirements and verified exclusions.

There is no universal latency, throughput, or percentage improvement that applies to every WordPress reverse-proxy deployment. Measure your own site before and after the change, using the same pages, traffic conditions, and cache state.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshoot the failures that appear most often

Infinite HTTPS redirects

  • Confirm NGINX sends X-Forwarded-Proto with the value produced by the public connection.
  • Confirm WordPress maps a trusted https value to $_SERVER['HTTPS'].
  • Check for a second proxy, CDN, Apache rule, or plugin forcing the opposite scheme.
  • Verify that the canonical URL constants and database URL options use HTTPS.

Use a redirect inspection tool or browser developer tools to identify which layer emits each Location response. The first redirect may be correct while a later layer sends the request back to HTTP.

Wrong-domain redirects or broken images

  • Check that Host is the public hostname and that X-Forwarded-Host identifies the same host.
  • Compare WP_HOME, WP_SITEURL, and the database’s home and siteurl values.
  • Look for absolute URLs saved with the origin hostname or HTTP scheme.
  • Check that proxy redirects are disabled with proxy_redirect off; unless you have a deliberate rewrite policy.

Login loops or lost sessions

Inspect the cookie domain, path, and scheme in the browser’s storage tools. Ensure the proxy preserves Set-Cookie behavior and does not rewrite the public host to an internal one. Remove competing SSL, URL, CDN, proxy, NGINX, or Apache settings one at a time. A login loop can be caused by a cookie that is scoped to the wrong hostname, a secure cookie delivered over an incorrectly detected HTTP request, or a redirect that changes the host between requests.

502 or 504 responses

  1. Verify the upstream name, address, port, and protocol in proxy_pass.
  2. From the proxy host, test the origin directly on that address and port.
  3. Check firewall rules, DNS resolution, listening sockets, and origin health.
  4. Read the NGINX error log at the time of the failure; distinguish connection refusal, timeout, and name-resolution errors.
  5. Check the origin web-server and PHP logs for crashes, worker exhaustion, or an invalid request path.

Private or stale content appears publicly

Disable HTML caching immediately, purge existing objects, and retest with an unauthenticated and an authenticated browser. Recheck exclusions for cookies, administrative paths, POST requests, previews, checkout, and account pages. Do not restore caching until a publish, login, logout, and personalized-content test all produce separate, correct responses.

Operational practices after launch

  • Document which layer terminates TLS and which layer owns HTTP-to-HTTPS and hostname redirects.
  • Record the trusted proxy addresses and the exact forwarded-header policy.
  • Monitor NGINX access and error logs together with origin and PHP logs so a public failure can be traced across the hop.
  • Retest the public hostname after certificate renewal, DNS changes, origin migrations, WordPress URL changes, and cache-rule edits.
  • Keep a tested rollback that routes traffic to the previous working edge or disables the new location without changing WordPress content.

The dependable sequence is simple: make the origin healthy, proxy it with the public host preserved, pass client and scheme identity, teach WordPress about trusted HTTPS, align every canonical URL, test all important paths, and only then introduce carefully scoped caching.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Frequently Asked Questions

Can NGINX reverse-proxy WordPress running on Apache?

Yes. NGINX can sit at the public edge and forward requests to an Apache-based WordPress origin, allowing Apache and its existing application features to remain in place while NGINX handles the public connection.

Which headers must NGINX forward to WordPress?

Preserve the public Host and forward X-Real-IP, X-Forwarded-For, X-Forwarded-Host, and X-Forwarded-Proto. Overwrite these values at a trusted proxy and prevent direct origin access so clients cannot spoof them.

Why does WordPress redirect forever between HTTP and HTTPS?

When NGINX terminates TLS but forwards HTTP, WordPress may see only the internal HTTP hop. Forward X-Forwarded-Proto and map a trusted HTTPS value to $_SERVER['HTTPS'] in wp-config.php; also remove conflicting redirects at other layers.

Should I cache WordPress pages at the reverse proxy?

Only after the uncached proxy works. Bypass shared HTML caching for logged-in and administrative requests, wp-login.php, all POST requests, carts, checkout, previews, comments, account pages, and any response that varies by user or cookie. Define and test purging before relying on cached HTML.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

What should WP_HOME and WP_SITEURL contain behind a proxy?

Use the public canonical URL, such as https://example.com, not the origin’s private hostname, port, or HTTP scheme. Keep those constants aligned with the database’s home and siteurl values and with the public Host header.

How do I diagnose a 502 or 504 from NGINX?

Verify the upstream address, port, protocol, DNS, firewall, and listening service. Test the origin directly from the proxy host, then correlate NGINX error logs with the origin web-server and PHP logs to distinguish refusal, timeout, resolution, or application failures.

The Bottom Line

Keep WordPress as the origin and NGINX as the public edge. Preserve the public host, forward trusted client and scheme headers, map proxy HTTPS in WordPress, align every URL, validate all user and API paths, and add narrowly excluded caching only after the basic proxy is correct.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More quests from Patch Notes

  1. How to Set Up a RedM (RDR2) Server in 2026: License Key, txAdmin and server.cfg, Step by StepBlog11min
  2. Best RedM (RDR2) Server Hosting in 2026: Comparing Four Hosts on Slots, Memory and PriceBlog10min
  3. How to Host a Mindustry Server in 2026: server-release.jar, Port 6567 and the Commands That MatterBlog7min
Recommended PC Tool
Recommended PC Tool
Windows Errors? Fix Them Before They SpreadFree repair scan
Crashes, No Sound, or Screen Glitches?Free driver scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.