It’s a little awkward but I’m just going to put this out there… I’ve got a thing for a good reverse-proxy. “Reverse-what?!” you say? “This is SFW right?!” I’m talking Reverse-proxy. And yes, yes it is. Now write this down because it’s about to change the game. According to Wikipedia…
“In computer networks , a reverse proxy is a type of proxy server that retrieves resources on behalf of a client from one or more servers. These resources are then returned to the client, appearing as if they originated from the proxy server itself.”
In layman's terms, a reverse-proxy is a routing strategy. One that hides the underlying destination from the end user. It's like a portal to another world (or server) but one that is hidden. The end-user has no clue they’re being served content from another place.
The reverse proxy pattern is a strong defense against distributed denial of service (DDoS) attacks. In fact, lots of enterprise clients route traffic through an intermediary like Akamai or Cloudflare. This mitigates vulnerability, handles bursts of traffic & aids in disaster recovery.
A common pattern is to route requests through an intermediary, which proxies those requests to servers that are not publicly accessible or knowable. Then, during periods of significantly increased traffic, Akamai can reroute that traffic within its infrastructure, allowing only legitimate requests to find their purchase.
The end-user never knows the difference.
Migrating projects to the Jamstack can be tricky, especially if the client has a significant investment in monolithic infrastructure. Rebuilding your website end-to-end means lost productivity, a distraction from daily operations and increased risk. Few clients can afford to rebuild every page on their site at once, so we need a more realistic strategy for encouraging clients to make the jump.
[Reverse proxy entered the chat]
Consider this: don’t worry about moving everything over at once. Move over your homepage, maybe a couple product pages and set up a reverse proxy for everything else to resolve back to your old infrastructure.
Over time, promote the outstanding pages to the new site without incurring the costs and anxiety associated with a big-bang cutover. This is called “phased adoption” and it’s great. The pattern itself is a generic one that can be implemented anywhere. However, we’re going to focus on Netlify because Jamstack.
Netlify makes this extremely easy with their flexible solution for rewrites and redirects. You simply place “rules” for routing traffic into a magic text file named "_redirects” and Netlify’s CDN will handle the rest. The syntax is surprisingly forgiving too.
When migrating over time, you typically only want to “forward” requests that cannot be served from the top of the funnel (or would otherwise throw a 404 error). Netlify makes this effort crazy trivial.
With just a single line in _redirects, you can tell Netlify to serve any physical pages deployed to the CDN and then proxy all the other traffic to your old site. For example…
For your convenience, we’ve prepared a Github repository containing the example snippet above and a few other files to illustrate the strategy. Everything has been deployed to Netlify which you can see here.
You can also click the button below to deploy this example to your own Netlify account…
You’ll notice that this codebase has two HTML files, representing two of our new pages (index.html & about.html). Also notice that when clicking through the example, those two files are rendering just as you’d expect (/ & /about, respectively).
Now here’s the cool part: when clicking through the navigation, the rest of the pages are resolving back to our old site (for example, /capabilities). Notice the hostname in your browser’s address bar doesn’t change as you click through the different links?
MAGIC, that’s what. For fun and profit!
Thanks to the redirect rule we placed into _redirects, any request for a file that doesn’t exist will be proxied to the old site and served as if nothing happened. And since the hostname stays consistent, the end-user never knows the difference!
This is a trivial use case but an extremely powerful concept. It can help you diversify cost over time while still paying down the technical debt of evolving towards a more modern online application.
As much as we love Netlify, their solution for redirects is not entirely free of criticism.
We’ve spent considerable time exploiting this feature to both gradually migrate legacy projects and architect entire systems behind reverse-proxies. One specific feature that is lacking on Netlify is the ability to interpolate environment variables within these rules.
What I really want to do is something like this…
…so I can deploy these rules across multiple projects (aka environments) and have them route accordingly based on that context. Since this feature was not natively supported, we created a shiny new build plugin that supports this exact feature!
At its core, this new build plugin is simply a string replacement library for environment variables. It will actually replace strings across your entire publish directory following each build.
Netlify-plugin-replace is open-source, published via NPM and is available for installation in your Netlify project directly through the admin UI. Take a look and please let us know what you think — comments, issues and pull-requests are welcome. We’d love to talk about how build plugins can solve your problems too!
Hopefully you can now appreciate my torrid love-affair with the reverse-proxy pattern (stop looking at me, swan). It may be some old-school sleight-of-hand, but when executed well, it can go a long way to reducing risk and operational impact to your next migration.
I’m giving a talk on this subject at the next Jamstack conference October 6-7, 2020. The conference has gone virtual this year and is free to attend. I highly recommend checking it out!
Sign up for our email newsletter. Nothing spammy about it. Just a monthly rundown of what we’re sharing.