Hardware FixRecommendedDevice not working? Your driver may be the problemCheck updates for common hardware issues.Fix DriversOctober 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 PC×
Skip to content
VGSources
Blog

How to Use Nginx as a Reverse Proxy for WordPress (HTTPS, Permalinks, and Client IPs)

A practical Nginx reverse-proxy guide for WordPress, covering Apache and PHP-FPM architectures, HTTPS termination, forwarded headers, rewrites, caching, testing, and 502 or redirect-loop fixes.
Length10 min Posted Quest giverVGSources Team

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.

Put Nginx in front of WordPress by terminating (or passing through) HTTPS at Nginx, forwarding the original host, scheme, and client address, and choosing the correct upstream protocol. Use proxy_pass when WordPress is served by Apache or another HTTP server; use fastcgi_pass only when Nginx sends PHP requests directly to PHP-FPM.

The details that prevent most failures are preserving Host and X-Forwarded-Proto, teaching WordPress that the public request is HTTPS, and adding Nginx rewrite handling because Nginx does not read Apache .htaccess files.

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.

Choose the WordPress architecture first

A reverse proxy is an HTTP gateway. Nginx accepts the browser request, sends a new request to an upstream server, receives the upstream response, and returns it to the browser. The upstream can be an HTTP WordPress server or a FastCGI PHP service; those are different protocols and require different directives.

Architecture Nginx does WordPress/PHP server does Rewrite ownership Typical failure boundary
Nginx → Apache (or another HTTP server) TLS termination, headers, connection handling, static proxying, optional cache Apache serves WordPress and invokes PHP Usually Apache and its WordPress rules Nginx-to-HTTP upstream connection
Nginx → PHP-FPM Static files, URL fallback, TLS, headers, and FastCGI requests PHP-FPM executes WordPress Nginx configuration, because there is no .htaccess equivalent Nginx-to-socket or Nginx-to-FPM connection

Many installations described as using Nginx still run Apache behind it. That arrangement lets Apache retain directory-level behavior, while a direct Nginx installation requires you to maintain every rewrite rule yourself. WordPress cannot generate Nginx rules automatically.

Plan the public and private endpoints

Before editing configuration, write down the values that must remain consistent:

  • The public hostname, such as www.example.com.
  • The public URL scheme, normally https.
  • The Nginx listener address and TLS certificate.
  • The upstream address and port if the backend is HTTP, or the exact PHP-FPM socket path if it is FastCGI.
  • The WordPress document root when Nginx serves files directly.
  • Which component owns redirects, rewrites, compression, and cache purges.

Point public DNS at Nginx, not at the private backend. Keep the backend reachable only from Nginx when the servers are split; this prevents clients from bypassing the proxy and seeing a different host, scheme, or security policy.

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

Configure Nginx as an HTTPS proxy to Apache

Use this pattern when Apache or another web server already serves the WordPress site over HTTP. The upstream name is local to Nginx; replace the address and port with the backend that actually serves WordPress.

upstream wordpress_backend {
    server 127.0.0.1:8080;
}

server {
    listen 80;
    server_name www.example.com example.com;
    return 301 https://www.example.com$request_uri;
}

server {
    listen 443 ssl http2;
    server_name www.example.com;

    ssl_certificate     /etc/letsencrypt/live/www.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem;

    location / {
        proxy_pass http://wordpress_backend;
        proxy_http_version 1.1;

        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 must point to an HTTP upstream. Do not put a PHP-FPM socket in this directive. The forwarded headers preserve the public host, the originating address, and the scheme that the browser used. proxy_redirect off prevents Nginx from rewriting backend Location headers unexpectedly; WordPress should generate URLs for the public hostname instead.

When the backend also uses HTTPS

For end-to-end TLS, define the upstream with an https:// URL and configure certificate verification appropriate to your internal certificate authority. The public request still needs the same host and forwarded-scheme headers. Terminating TLS only at Nginx is simpler, but the Nginx-to-backend hop is plain HTTP; end-to-end TLS protects that hop when it crosses an untrusted or separately administered network.

Serve WordPress directly with Nginx and PHP-FPM

Use this pattern when Nginx owns the document root and PHP-FPM is the application runtime. The socket name below is an example only; distributions and PHP versions use different paths, so inspect the PHP-FPM pool configuration and substitute the actual socket.

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

    root /var/www/wordpress;
    index index.php index.html;

    ssl_certificate     /etc/letsencrypt/live/www.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ .php$ {
        try_files $uri =404;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param HTTPS $https if_not_empty;
        fastcgi_pass unix:/run/php/php8.2-fpm.sock;
    }

    location ~ /.ht {
        deny all;
    }
}

try_files serves an existing file or directory and sends a missing path to index.php, which is the Nginx equivalent of the front-controller fallback WordPress expects. The PHP location must pass the script filename and the installation’s FastCGI parameters. A wrong socket path, a stopped PHP-FPM service, or permissions that prevent Nginx from opening the socket will produce a 502 response.

Use a separate port-80 server block to redirect HTTP to the canonical HTTPS hostname, as in the proxy example. If the site intentionally supports more than one hostname, decide which one is canonical before enabling redirects; otherwise WordPress and Nginx can redirect requests back and forth.

Preserve headers and make WordPress aware of HTTPS

Nginx changes the Host and Connection headers in proxied requests unless you set them explicitly. WordPress also needs to know that the original browser connection was HTTPS when TLS ended at Nginx. Without that information, it may emit HTTP links or redirect an already secure request to HTTPS repeatedly.

In a proxy-to-HTTP deployment, add the following logic to wp-config.php before WordPress loads its bootstrap file:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
    $_SERVER['HTTPS'] = 'on';
}

Only trust this header when requests can reach WordPress through your controlled proxy. Nginx should overwrite the incoming value with $scheme, as shown earlier, and the backend firewall should prevent clients from connecting directly and supplying a forged header.

Set the WordPress address and site address to the public URL, either in the WordPress settings or with constants when configuration must be immutable:

define('WP_HOME', 'https://www.example.com');
define('WP_SITEURL', 'https://www.example.com');

Do not set these values to an internal hostname or to an HTTP URL when the public site is HTTPS. If the database already contains old values, changing only Nginx will not repair links stored in content, plugin settings, or serialized options; update those through a method that understands serialized WordPress data.

Handle permalinks when Nginx is in front

Proxying to Apache

Apache remains responsible for interpreting its WordPress rewrite rules. Confirm that the backend virtual host accepts the public request path and that its WordPress front-controller rule sends unknown paths to index.php. Nginx should proxy the complete URI rather than trying to reproduce Apache’s rules prematurely.

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

Running Nginx directly

Nginx has no directory-level .htaccess file. Keep the try_files $uri $uri/ /index.php?$args; fallback in the server configuration and reload Nginx after changes. This is what makes paths such as a post permalink, a category archive, and a REST endpoint reach WordPress instead of returning a file-system 404.

Do not copy arbitrary Apache directives into Nginx syntax. Translate only the rules the site needs, and test plugin-specific endpoints separately; security, multilingual, and caching plugins can add paths that are not covered by a minimal WordPress example.

Install and activate the configuration safely

  1. Point the public DNS record at the Nginx address and wait for the intended DNS records to be visible.
  2. Install the TLS certificate and private key on Nginx, with file permissions that allow Nginx to read the key but not ordinary users.
  3. Create the appropriate HTTP-to-HTTPS redirect and HTTPS server block.
  4. Choose proxy_pass for an HTTP backend or fastcgi_pass for PHP-FPM. Never substitute one for the other.
  5. Add the host, client-IP, forwarded-host, and forwarded-proto headers for a reverse-proxy deployment.
  6. Set WordPress’s public home and site URLs and add trusted-proxy HTTPS detection when TLS terminates at Nginx.
  7. Add the rewrite fallback if Nginx serves WordPress directly; do not expect WordPress to create it.
  8. Check syntax before applying the change: nginx -t. Fix every reported error rather than reloading a partial configuration.
  9. Reload Nginx with the service manager used by the operating system, for example systemctl reload nginx, so existing connections can finish.
  10. Test through the public hostname, not only through localhost: the home page, one pretty permalink, /wp-admin/, a login and logout cycle, a form submission, and representative CSS, JavaScript, image, and upload URLs.

Choose where TLS terminates

Choice Advantages Costs and checks
TLS at Nginx; HTTP to backend One certificate endpoint, simpler backend configuration, and straightforward proxying The internal hop is unencrypted; WordPress must trust the forwarded HTTPS scheme and the backend must be isolated from direct clients
TLS at Nginx and backend Encryption continues across the internal hop and is useful across hosts or networks Two certificate paths, upstream TLS verification, and possible hostname/SNI issues must be maintained
Single server Low network overhead and simpler local addressing A failure or resource exhaustion on that host affects Nginx, the web server, PHP, and WordPress together
Split servers Separate scaling, isolation, and independent service limits Firewall rules, private routing, health checks, and accurate client-IP trust become essential

Forward the real client IP safely

X-Real-IP carries the address seen by Nginx, while X-Forwarded-For appends that address to the existing forwarding chain. Applications, rate limits, audit logs, and security plugins must be configured to trust these headers only from known proxy addresses. If every incoming value is trusted, a direct client can forge an address; if none is trusted, logs and access controls show the proxy instead of the visitor.

Keep the header chain consistent at every proxy hop. Use the public forwarded host when the backend generates absolute URLs, and verify that the backend does not replace it with an internal name. This resolves incorrect redirects, password-reset links that point to private addresses, and mixed-host canonicalization.

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

Add full-page caching only with a purge plan

Nginx can cache FastCGI responses and reduce requests reaching PHP-FPM. A usable design needs a cache zone, a deterministic cache key, rules for stale responses, and an invalidation path. WordPress’s Nginx guidance describes these pieces and notes integration with the Nginx Helper plugin for purge requests.

Start uncached while validating the site. If you enable caching, bypass it for every request that can be personalized or change state:

  • Logged-in users and administrator screens.
  • Requests carrying the site’s authentication or preview cookies.
  • POST, PUT, PATCH, and DELETE requests.
  • Checkout, account, search, comment, preview, and other plugin-defined dynamic endpoints.
  • Responses that set private cookies or otherwise instruct intermediaries not to store them.

Define whether publishing, editing, deleting, commenting, changing menus, and changing widgets purge the affected URLs before turning on full-page caching. Without a purge process, visitors can continue receiving old pages after an edit. Exact cookie names and bypass expressions depend on the plugins and authentication scheme installed on the site, so copy them from the running deployment rather than using a universal pattern.

Diagnose common failures

Symptom Likely cause Checks and correction
Infinite HTTP/HTTPS redirect loop WordPress does not recognize the proxy’s HTTPS scheme, or its home/site URLs disagree with the public URL Confirm Nginx sends X-Forwarded-Proto $scheme, add trusted-proxy detection in wp-config.php, and make both WordPress URLs use the canonical public scheme
Redirects to an internal hostname or wrong domain The backend receives or generates the wrong host Set Host $host and X-Forwarded-Host $server_name; check canonical URL settings and backend virtual-host selection
Logs show only Nginx’s address The client-IP headers are missing or the backend does not trust the proxy Pass X-Real-IP and X-Forwarded-For, then configure trusted proxy handling in the backend and logging layer
Pretty permalinks return 404 Nginx has no front-controller fallback, or Apache’s backend rewrite is incomplete For direct Nginx, use try_files to /index.php?$args; for Apache, test its WordPress rewrite and virtual-host configuration
502 Bad Gateway Wrong upstream address, port, protocol, firewall rule, stopped service, or inaccessible PHP-FPM socket Verify reachability from Nginx, match proxy_pass to HTTP and fastcgi_pass to FastCGI, check PHP-FPM status and socket permissions, and inspect Nginx’s error log
Static files are missing or have incorrect URLs Wrong document root, host/scheme settings, or an over-broad location rule Check the file path and permissions, request the asset through the public hostname, and inspect the generated URL in the page source
Edits or comments appear stale FastCGI cache is serving an old response or purge hooks are incomplete Temporarily bypass cache, review authentication and POST bypass rules, and test the configured purge integration

Use a repeatable verification checklist

  • Run nginx -t after every configuration edit.
  • Verify the certificate name, expiration, and complete chain from an external client.
  • Request the home page and inspect the final status code and canonical URL.
  • Open a newly created pretty permalink and an older permalink.
  • Sign in, visit /wp-admin/, and confirm that the session remains secure without a redirect loop.
  • Submit a harmless form and verify that POST requests are not cached.
  • Inspect access logs for the expected host and client address.
  • Request CSS, JavaScript, images, and an uploaded media file.
  • Check a REST API request and any plugin-specific dynamic endpoint.
  • After enabling cache, edit a page and confirm that the defined purge process removes the old version.

Operational decisions that prevent future outages

Keep rewrite ownership explicit

Document whether Apache or Nginx owns each rewrite. A later administrator should not add a second redirect layer without knowing which server already canonicalizes the URL.

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

Keep proxy trust narrow

Record the proxy addresses trusted to set forwarded headers. If the topology changes, update that allowlist and test logs and HTTPS detection before exposing the backend again.

Keep a rollback path

Save the last known-good server block, test new files with nginx -t, and reload rather than restart when possible. If the new proxy fails, restore the previous configuration or temporarily point DNS at the known-good endpoint while you correct the upstream, certificate, or rewrite error.

Nginx is a reliable WordPress front end when the boundary is deliberate: HTTP backends use proxy_pass, PHP-FPM uses fastcgi_pass, forwarded headers preserve the public request, WordPress is told when TLS ended at the proxy, and Nginx rewrite and cache behavior is maintained as configuration rather than assumed to come from .htaccess.

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
PC Slower Than It Used to Be?Free scan - under a minute
Outdated Drivers Are Slowing You DownFree scan - exact matches

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.