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 blog.anuvawines.com, but be accessible from anuvawines.com/blog (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 domain.com/blog/ to blog.domain.com. 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 domain.com/

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

location /blog/ {
 proxy_pass http://static.anuvawines.com/wordpress ;
 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 mydomain.com/blog 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 subdomain.mydomain.com/, when they should be accessed by domain.com/blog

add a few lines to your wp-config.php

define('WP_HOME', 'http://mydomain.com/blog');
define('WP-SITEURL', 'http://mydomain.com/blog');

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.

subdomain.mydomain.com/login will redirect to mydomain.com/blog 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, anuvawines.com/blog

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

19 Comments

  1. Ricardo says:

    I found this software to gain a list with 200 fresh functional proxy:

    http://www.tradebit.com/filedetail.php/116451290-fresh-proxy

    hope you find it usefull.

  2. Skaurus says:

    Better solution: http://cobaltedge.com/wordpress-nginx-subdirectories-and-separate-s

    In short, on subdomain you should put wordpress files in same subdirectory as it will be on main site and then edit couple of settings via web admin interface.
    Works flawlessly…

    1. Yuji says:

      Nice! That’s a good idea.

      You’re saying set up the subdomain to host the blog in blog.example.com/blog, then proxy the example.com/blog 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 : )

  3. Flackou says:

    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,

    Julien

    1. Yuji says:

      I’m sorry Julien,

      It was more trouble than it was worth for me – I decided to serve php directly via Nginx.0

    2. Yuji says:

      I’m sorry Julien,

      It was more trouble than it was worth for me – I decided to serve php directly via Nginx.

  4. thomas.uhle@reflact.com says:

    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?

  5. blakeimeson says:

    It is a little different setup but I ended up writing a tutorial on this. Your post was one I stumbled on researching trying to find some clues 🙂

    https://fewerthanthree.com/tutorial/wordpress-multisite-reverse-proxy-setup-wpengine/

  6. Peter says:

    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.

  7. vovcat says:

    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 “facing.site.name” line in .htaccess file inside wordpress subdirectory (subdirectory was the same on the frontend and backend).

  8. Luke Burden says:

    Hi Yuji!

    Just read your post. At Poparide (www.poparide.com) 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:

    https://www.poparide.com/blog/how-to-host-wpengine-blog-in-subdirectory-using-reverse-proxy/

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

    Luke

Leave a Comment