Nginx / WordPress — Proxy Subdirectory to WordPress Subdomain

Using Nginx to proxy a subdirectory to a wordpress installation on a subdomain.

I’m moving our blog onto our main site, but want to keep them on separate servers from the main site for various reasons.

The blog will be on, but be accessible from (for SEO, since google thinks of subdomains as separate sites).

Double Update: Don’t do it!

It’s more trouble than its worth for me — I simply bought a bigger server to handle a separate PHP process and let nginx actually serve it at /blog/.

Update: I ran into issues with permalinks due to the proxy. It looks like WP checks the ‘home’ option against something to pull the post_ID from your permalink format. I tried digging in and replacing option_get(‘home’) where i thought the ID was being generated, but couldn’t solve the issue.

My end solution was to set the home field to the real address where WP is hosted, and to edit the link generator itself to pull data from a new option field I made called proxy_home.

That way, all my issues were solved.

For my peace of mind, I made my subdomain return a 403 forbidden if a certain header was not passed to the subdomain on proxy.  Of course, this could be any other method that generally IDs the proxy server (ip/referrer/whatever). The reason is not for security, so anything goes.

Set up the nginx proxy

Say we want to proxy to Note that I say proxy, because we don’t want a redirect. We want a 200 http status message. One that google will crawl as apart of

Set up a location in your /etc/nginx/nginx.conf aside your other location directives.

location /blog/ {
 proxy_pass ;
 proxy_set_header X-Real-IP $remote_addr;
 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

Restart nginx, and you’re good to go. Visit the and you will be able to navigate to the site, with an HTTP 200 message.

The only problem is that the links are still using the subdomain address, and if you tried admin authentication, it fails.

Set up wordpress links to use proxy address

This is pretty much good to go out of the box, but you will have to change your WordPress installation to rewrite the urls for your proxy domain instead.

Right now, all links are, when they should be accessed by

add a few lines to your wp-config.php

define('WP_HOME', '');
define('WP-SITEURL', '');

Reload the page and your urls should be set to the new ones.

Fixing admin/authentication for proxy address

Suddenly, we have a problem. We can’t log in via the proxy, OR the actual subdomain address because we set the above 2 lines. will redirect to and fail.

I dug around the cookie headers to see that wordpress is looking for a database entry called home and siteurl to set these cookies. The above code fixed our links, but these cookies look directly at the db. I suspect this means the above step is useless.

So, go into your mysql db, alter the wp_options table, option_name “siteurl” and option_name “home”, and set them to the proxy address.

In my case,

The cookies will now match the domain when you are logging in via the proxy address.


    1. Nice! That’s a good idea.

      You’re saying set up the subdomain to host the blog in, then proxy the requests and wordpress won’t complain because it’s already expecting to be at /blog?

      I gave up and ran php on my main webserver : )

  1. Hi,

    Thanks for this very interesting tutorial. We’re in the same situation as you were (WordPress served by Apache behind a Nginx proxy) and we are experimenting trouble : could you detail how you solved the situation ?

    Thanks a lot in advance for your help,


  2. Since WordPress 4.1.1 I run into the “too many redirects issue”. Is Yujis solution still working wight now or has the same problem?

  3. Nice insight on how you tried and solved this. I am also currently struggeling with a simple blog solution to be served under a /blog/ directory. I will let you know and maybe write a few lines about the technics used.

  4. Thank you! Your post was one that helped to understand the problem I had. So WP_SITEURL and WP_HOME are not about frontend-vs-backend URLs but for self links and a way to find wordpress files. My case was solved by adding RequestHeader set Host “” line in .htaccess file inside wordpress subdirectory (subdirectory was the same on the frontend and backend).

  5. Hi Yuji!

    Just read your post. At Poparide ( we had reasonable success treating our WordPress instance (on WPEngine) as a black-box and Nginx as a reverse proxy in front of it. This meant we could keep our WordPress config as a simple as possible.

    Thought you might like to compare notes:

    Let me know what you think, and thanks for your post. 🙂


Leave a Comment

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s