-
Reverse Proxy from IIS Website to WordPress
Our client has a corporate site at www.domain.com hosted on IIS and the blog hosted on a subdomain on a separate LAMP server at blog.domain.com. Our client feels serving their blog up under www.domain.com/blog will help their SEO and they will rank better (this is debateable but what client wants is what they will get).
The objective of this project is to serve a wordpress site on a linux server under a subdirectory on IIS. In order to accomplish this we need to setup IIS to act as a reverse proxy, thus serving the the wordpress site under the desired blog subdirectory.
The first step is to make sure your version of IIS is compatible (IIS 7+). Once you have determined this, you will need to install the Application Request Routing Module. The easiest way to go about installing these is using the
Windows Platform Installer. This will install the ARR module and all of its dependencies, the URL Rewrite Module being one of them.Once installed, open IIS Manager, select the Server and open Application Request Routing Cache:
On the following screen, select Server Proxy Settings from the right hand side:
Finally, select Enable Proxy:Now that the proxy is enabled, we need to modify the web.config in the root of www.domain.com (or create a folder called /blog and add the web.config into there) to add the rewrite rule that will proxy our request from IIS to wordpress. You add these settings into the <configuration>
<system.webServer> element:<rewrite> <rules> <rule name="Reverse Proxy to WP" stopProcessing="true"> <match url="^blog/(.*)" /> <action type="Rewrite" url="https://blog.domain.com/{R:1}" /> </rule> </rules> </rewrite>
We can now go to www.domain.com/blog and see the wordpress blog, fantastic but we aren’t done yet are we. If you made a subfolder named /blog for the web.config, you need to open IIS manager and convert it to an application before you will see the site (any .net version and app pool will be fine – I made one called reverseproxy, latest .net and classic mode instead of integrated).
For the sake of simplicity, here is the finished web.config without explanations (I will get to explaining all the pieces eventually and adding pretty pictures for those that can’t read HA)
<rewrite> <rules> <rule name="Reverse Proxy" to WP stopProcessing="true"> <match url="^blog/(.*)" /> <action type="Rewrite" url="https://blog.domain.com/{R:1}" /> </rule> </rules> <outboundRules> <rule name="ReverseProxyOutboundRuleWP" preCondition="IsHtml"> <match filterByTags="A, Form, Img, Script" pattern="^http(s)?://blog.domain.com/(.*)" /> <action type="Rewrite" value="http{R:1}://www.domain.com/blog/{R:2}" /> </rule> <preConditions> <preCondition name="IsHtml"> <add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" /> </preCondition> </preConditions> </outboundRules> </rewrite>
Now you need to change the Site Address (URL) in the wordpress dashboard (wp-admin) under Settings -> General to your www.domain.com/blog/ address but leave the wordpress address as the subdomain blog.domain.com.
While the above makes the site work the wp-admin folder does NOT work off the proxied domain as wordpress force redirects you out of the /blog directory back to the parent. Apparently we haven’t solved this problem yet with an .htaccess or IIS and sites are managed under the subdomain in this case. We also noticed that some URL’s are still coming back with the blog.domain.com as the source on some theme files, so that is another problem to deal with before we can lock the server down to just the ARR proxy IP.UPDATE ON WP-ADMIN REDIRECTING FROM SUBFOLDER – FIXED:
So to stop the wp-admin from redirecting you will need to add another reverse proxy but this time focusing on wp-admin. The first thing you should do is create a folder named wp-admin in the root of your IIS website.Now copy the config you made above but edit it to focus on just wp-admin URL’s. It should look like this:
<rewrite> <rules> <rule name="Reverse Proxy wp-admin" to WP stopProcessing="true"> <match url="^wp-admin/(.*)" /> <action type="Rewrite" url="https://blog.domain.com/wp-admin/{R:1}" /> </rule> </rules> <outboundRules> <rule name="ReverseProxyOutboundRuleWP-admin" preCondition="IsHtml"> <match filterByTags="A, Form, Img, Script" pattern="^http(s)?://blog.domain.com/wp-admin/(.*)" /> <action type="Rewrite" value="http{R:1}://www.domain.com/blog/wp-admin/{R:2}" /> </rule> <preConditions> <preCondition name="IsHtml"> <add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" /> </preCondition> </preConditions> </outboundRules> </rewrite>
Place this web.config file in the newly created wp-admin folder.
Now go into IIS manager and convert this folder into an application, any .net version will suffice and classic versus integrated does not matter for this. You could add this to your root web.config as well if you wish.Now log into your site via the blog.domain.com URL and go into general and change both the WordPress URL and the site URL to www.domain.com/blog. That is the LAST time you will ever see blog.domain.com unless you change the URL in the wp_options table.
IMPORTANT: If you change permalinks after making this change (or anything else that may change your .htaccess) your site could break as wordpress will rewrite your .htaccess changing the rewriteBase and rewriteRule to reflect this new ‘location’, we do not want this so make sure your .htaccess is still the default settings and NOT setup for a subdirectory. It should look like this:
# BEGIN WordPress <IfModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteRule ^index\.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] </IfModule> # END WordPress
WordPress will want to try to adjust it to be this, this is BAD:
# BEGIN WordPress <IfModule mod_rewrite.c> RewriteEngine On RewriteBase /blog/ RewriteRule ^index\.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /blog/index.php [L] </IfModule> # END WordPress
You will know if this happened as EVERYTHING will break as nothing exists there on the source server.
Now, ff you want wordpress and wp-admin to work without 2 reverse proxies, the solution IS to change blog.domain.com to a blog.domain.com/blog/ URL. So the first thing you will need to do is move or copy your wordpress site to a new ‘blog’ folder under blog.domain.com/blog. You will need to update the wordpress URL to this new location and update the site URL as per above to www.domain.com/blog. If you want more details on how to move your wordpress blog, that is a scope beyond this article but leave a comment and I can google it for you ;) Go to blog.domain.com/blog to make sure everything is working as it should (you may need to remove the root .htaccess in blog.domain.com…).
Under your www.domain.com make a folder called blog on the windows server. Now go to IIS manager and convert this folder into an application, you can create a new app pool and the .net version doesn’t really matter. It is recommended to set this pool to classic vs integrated mode but again this really doesn’t matter for wordpress as we just are using this to make the web.config work. Now you will need to update the web configuration file in the blog folder.
Here is the web.config for this:
<rewrite> <rules> <rule name="Reverse Proxy" to WP stopProcessing="true"> <match url="^(.*)" /> <action type="Rewrite" url="https://blog.domain.com/blog/{R:1}" /> </rule> </rules> <outboundRules> <rule name="ReverseProxyOutboundRuleWP" preCondition="IsHtml"> <match filterByTags="A, Form, Img, Script" pattern="^http(s)?://blog.domain.com/blog/(.*)" /> <action type="Rewrite" value="http{R:1}://www.domain.com/blog/{R:2}" /> </rule> <preConditions> <preCondition name="IsHtml"> <add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" /> </preCondition> </preConditions> </outboundRules> </rewrite>
You can now change both the wordpress URL and the site URL to www.domain.com/blog.
You are finished now and running your wordpress blog under your parent domain via IIS proxy under a subfolder. There are still some things you may have to do, and I suspect lots of plugins will break with this but hey, it’s something at least. If you are not allowed to install PHP on your production IIS web server, then this is likely your only option to try to serve those overbearing SEO SOB’s MOZ recommendation of putting a blog under a subfolder. IMO if you are doing this before moving your blog.domain.com to SSL and seeing how that affects your rankings then that is your prerogative. I’m in the subdomain camp on this one, but have to support those subdirectory folk as well.
A couple of notes:
If you are getting a ‘jquery is not defined’ error on load-scripts.php when entering wp-admin, which is likely as I tested this on the latest version of wordpress (4.7.3), you will need to set the WordPress script debug to true in the wp-config.php:
Error:
Uncaught ReferenceError: jQuery is not defined
at load-scripts.php:1define( 'SCRIPT_DEBUG', true );
The reason for this appears to be due to the minification of the javascript on wordpress core files and IIS ARR not getting along nicely. Debug scripts are not minified hence why I believe it works with that on.
Another secret – if using NGINX – you might need to adjust your try_files directive rule to something like this to handle the subfolder and proxy to a php-fpm service:
try_files $uri $uri/ /index.php?q=$uri&$args;
rewrite ^([^.]*[^/])$ $1/ permanent;
Another note, if you are getting a 500.52 error about “Outbound rewrite rules cannot be applied when the content of the HTTP response is encoded (“gzip”)” – You need to add the following to your web.config on the inbound rewrite rule below the rewrite action (or disable compression on the source server).
<serverVariables> <set name="HTTP_ACCEPT_ENCODING" value="" /> </serverVariables>
You may need to add this as a Server Variable under URL rewrite if you get an undeclared error.
6 responses to “Reverse Proxy from IIS Website to WordPress”
-
So, what’s the rest?
I’m trying to do this very thing now. I’ve got the inbound working somewhat, it routes to the unix server and I can see content, but no resources work right, I think because the url has https from our main site, but all the resources on the blog are http. -
Albert Trotter April 9th, 2017 at 11:44
i m facing problem in web.config file …in match tag
Leave a reply
-
Andrew March 10th, 2017 at 11:15