How to: Setup an Nginx reverse proxy for a blog

Updated: February 11, 2023 Reading Time: 4 minutes stage: complete
Table of contents
Share this

When it comes to implementing reverse proxies, there are many guides and tutorials out there but they all seem to suffer from the “hello world” problem: they explain what a reverse proxy is but when they implement it they stop at a very basic and often not realistic implementation.

This post is different.

I’ll assume you already know what a reverse proxy is (if you don’t, I’ve written an introductory post here) and you are just here for the implementation details.

Reverse Proxy for a Blog

I want to implement a reverse proxy to redirect a portion of the traffic that reaches my server to a different origin server than the one I have configured with NGINX.

In particular, any time someone visits mysite.com/blog I want to serve them content from a Webflow site (mysite.webflow.io) rather than serving them content from my server directly.

The problem I want to solve is not merely proxying the requests (that is just one NGINX command) but also ensure that all the blogposts I currently serve from mysite.com are redirected correctly (with a 301 permanent redirect) to my new blog hosted on Webflow.

To recap, we want:

  • map mysite.com/blog to mysite.webflow.io
  • ensure that the user never sees the mysite.webflow.io domain in their browser
  • ensure all blogposts are still accessible from Webflow
diagram of a reverse proxy configuration
reverse proxy configuration for mysite.com

Enough preliminaries, let’s edit some configuration files!

Adding the 301 redirects to NGINX

Before we add any rules to our NGINX configuration we need to create mapping rules for all the blogposts we’ve migrated to Webflow.

This would’ve been very easy had the blogposts been inside a folder in the first place (something like mysite.com/articles or even mysite.com/blog), but for historical reasons the content is spread in multiple subfolders (mysite.com/info/article-1, mysite.com/article-2, mysite.com/info/blog/article-3).

In Webflow we did the right thing and migrated all the articles into the same folder: mysite.com/blog/article-1, mysite.com/blog/article-2, and so on.

The trick here is to get the list of all the pages we want to redirect and build a redirects file and add mapping directives in NGINX.

Step 1: Build the redirects.conf file

Gather all the pages that need to be redirected and build a redirects.conf file.

Each entry should have the following format (one per line):

old-path new-path;

For example

article-2 /blog/article-2;
/info/blog/article-3 /blog/article-3;
...

Move this file to the same location where your nginx.conf file is located

Step 2: Add the mapping rules to NGINX

Time to edit our nginx.conf file.

We need to add one directive to load the redirects.conf file and establish the mapping from old paths to new paths.

Add the top of your nginx.conf file (or anywhre outside the server {} block) add the following:

map_hash_bucket_size 128;
map $request_uri $new_uri {
    include redirects.conf;
}

Line 1 is just there to prevent any errors in case we have very long URIs in our redirects.conf file (I’ve used up to a size of 256 in some cases).

Lines 2-4 tell NGINX to try and match an incoming request ($request_uri) to a new one if the mapping is present in the redirects.conf.

Step 3: Add the 301 redirect rule

At this point NGINX is already mapping our old URIs to the new paths, but nothing will work for two reasons:

  1. We are not telling NGINX what to do with those mappings and we don’t have any pages that match those path in our server

  2. We haven’t configured the reverse proxy yet.

Before moving on to the reverse proxy rules, all we need to do is add the following directive inside the server{} block in our nginx.conf file:

if ($new_uri){
    return 301 $new_uri;
}

This directive simply tell NGINX to perform a 301 redirect whenever it gets a request for $new_uri.

For example if you navigate to mysite.com/info/article-3 NGINX will perform a 301 redirect to mysite.com/blog/article-3. All good up to here, but you’ll get a 404 in the end because we haven’t redirected traffic to our Webflow site where the blog lives now.

Implementing the Reverse Proxy in NGINX

At this point all that’s left to do is easy. We need to add a proxy_pass directive to redirect /blog requests to our Webflow site.

Paste the following code inside your server {} block:

location /blog {
    proxy_pass mysite.webflow.io;
    proxy_set_header Host $host;
    break;
}

Let’s unpack a what’s happening here:

Line 1 just tells NGINX that something needs to be done when /blog requests are incoming

Line 2 is the actual reverse proxy. It will path all requests to /blog/* to our Webflow site.

Line 3 ensures that our Host header matches our root domain mysite.com. This will tell the browser to show mysite.com/blog and not mysite.webflow.io/blog in the url bar.

Line 4 tells NGINX to stop processing the rewrite rule at that point. This is needed only if you have redirects like the ones we’ve configured above. Otherwise you might enter in a redirect loop causing all your pages to display the ERR_TOO_MANY_REDIRECTS error.

Now, just reload the config or restart NGINX and we’re good to go! 🚀