A comprehensive overview of the setup for a WordPress Multisite subdirectory install hosted on WPENGINE running through a Fastly Load Balancer to a client’s server in Reverse Proxy configuration
This tutorial represents much time, frustration, and eventual joy. Our team hopes it will be helpful to others. Please feel free to comment and help us make this better.
If you need help, reach out to us. If you find it valuable, please share, like, and comment!
Tutorial Version 1.1.2
To use a Reverse Proxy and have a site at originalsite.com appear to live at finalsite.com/blog and SEO-migrate from one to the other.
Original multisite blogs
originalsite.com/site2/ , etc.
Final multisite blogs
finalsite.com/blog/site2/ , etc.
Final admin site
Final admin multisite blogs
originalsite.com/site2/ , etc.
Example domains to protect client privacy
Why have a site in this set up?
Having a site on a subdirectory (originalsite.com/blog/) rather than a subdomain (blog.originalsite.com) can have vastly greater positive SEO impact. This impact goes both for the actual WordPress site but anything else on the primary domain. Ranking potential is far greater having a site in .com/blog format as it gets the benefit of the domain strength in a far tighter manner than a subdomain.
Often a WordPress site can’t be actually installed on the root domain’s server. It can make sense to have it segmented for security or on WordPress-specific hosting. This lets the main site keep its server and application siloed. In Reverse Proxy setup a subdirectory like this can be excluded from PCI-compliance if the main site is running Ecommerce or similar.
One of the main advantages of this setup is that you can keep WordPress accessible at a subdomain and let the WPENGINE staging setup stay intact. You aren’t then fighting against WordPress or the hosting platform! While we chose to have ours located at admin.originalsite.com, there is no reason you couldn’t also have it live at admin.finalsite.com or similar.
There ends up being an entire multisite that lives at admin.originalsite.com. This allows you to create a global 301 redirect on originalsite.com and www.orginalsite.com to make sure all existing rankings and references are properly redirected.
All the site URLs on the backend will stay http://admin.originalsite.com
Using a special Reverse Proxy WordPress plugin, the URLs will be rewritten to match the end destination of https://www.finalsite.com/blog/
It is important that WordPress URLs are all set to http or WPENGINE will interfere with the process.
WordPress – Reverse Proxy Plugin
This plugin is partially inspired by this one by JamesPaden. You Network Activate the plugin.
What this plugin will do is test if we’re on the front-end of our correct site (so we don’t mess up the admin controls as well as any testing or staging sites). If so, we’ll update all the original site URLs and replace with “https” versions of the final site URLs.
Additionally, if using the Yoast SEO plugin this will replace all the canonical URLs globally so there will never be any versions of the admin controlled version of the site getting indexed as the original source for the content.
WordPress – Autoptimize Plugin
We are using the WordPress Autoptimize plugin to concatenate, minify, and compress the HTML and CSS.
Make sure to have the CDN filled in with your final site full URL or finalsite.com/blog may not render.
WordPress – wp-config.php
wp-config.php file will stay much the same as you would expect for a multisite setup. Primary thing to add are your Purgely keys to help Fastly work well using the Purgely plugin.
WordPress – .htaccess
.htaccess file in the root of Original Site has a typical setup for WordPress Multisite. There is nothing special about the setup of this file for the Reverse Proxy.
Original Site – DNS
The originalsite.com domain’s
A record point to the WPENGINE install IP address or install CNAME if you are using CloudFlare CNAME Flattening. The
WWW CNAME points to the install CNAME.
The originalsite.com admin CNAME record points to Fastly e.g. global.prod.fastly.net
If you are pointing to a Fastly SSL the CNAME will be different and you’ll need to first add a TXT verification record.
Original Site – Global Redirects
We are using a global 301 redirect to send any requests to the original site to new equivalent URLs. This way the SEO trust of the original site gets passed on and rankings preserved. As well, if any blogs have linked to the old URLs, we’ll preserve the user experience.
[Thanks J. Withee for the RegEx help]
Make sure there is only one 301 “hop”. The more hops in the chain, the more it reduces the SEO strength being passed. (Redirect Checker Tool) This is why I have www and non-www added as separate domains in WPENGINE…
If the final site is https then you will for sure need your admin.orginalsite.com to be properly SSLed or you will have mixed content warnings and things won’t work right.
This was a tricky part of the process and key to it working. Here is what our SSL configuration looked like in WPENGINE. Don’t force non-SSL.
We also ended up needing a Fastly “Shared Certificate Service” SSL .
Final Server – Reverse Proxy Setup
This goes on the finalsite.com server:
That is for an Apache Virtual Host but similar configurations can be created for nginx or Microsoft IIS setups.
Fastly CDN / Load Balancer
This is an important part of the whole equation. It caches and ensures that the bulk of the load is handled by the Fastly network, not WPENGINE. You wouldn’t (likely) be able to leverage WPENGINE’s caching and architecture if you went direct. A traffic spike would then be crippling. Post-launch without much optimization our site is consistently loading between 1 and 1.3 seconds.
Purgely Plugin – A plugin to manage Fastly caching behavior and purging
Install and Network Activate this: https://wordpress.org/plugins/purgely/
Source on Github: https://github.com/CondeNast/purgely
The Fastly IPs were whitelisted at WPENGINE from https://docs.fastly.com/guides/securing-communications/accessing-fastlys-ip-ranges
Fastly is built on Varnish and can use VCL (Varnish Configuration Language). Here is a link to our anonymized complete VCL that is assembled from all the following. One of the Pre-Launch checks is to look over the generated VCL and make sure all the URLs are correct.
There were several custom rules that were created so that our headers from finalsite.com/blog/ were getting passed through to end up being able to be addressed by the WordPress Reverse Proxy plugin.
Fastly – Domain
Fastly – Backend Origins
If you are using WPENGINE, make sure that for the secure host (443) not just Certificate Hostname but also SNI Hostname are both set to admin.originalsite.com.
Fastly – Override Host
Fastly – Headers forwarded
There are 5 headers configured to be passed. (“Ignore if set” on all of them)
IF No headers for Original
req.http.Host != “admin.originalsite.com”
HTTP_X_FORWARDED_SERVER required by WPEngine
X-Forwarded-Server for WPEngine backend
This particularly client uses Kapost for editorial management. The brilliant folks there were kind enough to get us a custom patch plugin that would make sure the URLs returned to the Kapost instance were the final URLs and not admin URLs. This is key for the Social sharing and Google Analytics components of the Kapost backend.
There is also a separate Multisite plugin for Kapost that is needed as well. So alongside the primary Kapost WordPress plugin, there are two others
We are big fans of WPENGINE but in the case of a Reverse Proxy you have to sidestep some of the platform features in order to make this work right.
- Disable WPENGINE’s object caching
- Disable WPENGINE’s auto-update WordPress Core – so we can properly test before major upgrades
- De-couple WPENGINE CDN if you were using it
Tips & Troubleshooting
- Resaving permalinks can be your friend
- In WPENGINE it may be helpful to “Reset File Permissions” and “Clear Cache”
- If admin.originalsite.com is appearing in the source on finalsite.com/blog you can go to WordPress’s Settings>>Writing for each install and uncheck “Convert emoticons like 🙂 and 😛 to graphics on display”
- It may be helpful to have the finalsite.com IP location set in your local Hosts file if there is other caching involved. In our case Akamai was in play as well.
- In Yoast SEO’s “Dashboard” >> “Company Info” we had to change the URL to be the finalsite.com image URL for the Company Logo
We’ve shared the Launch Checklist we used.
- Reverse proxy and WordPress from Edmund Turbin
- Note: Pressable pulled this post down but it was key for our early understanding: (Cached) Reverse Proxy Plugin for Using a Hosted WordPress Site in a Subdirectory