Application request routing for Hugo on IIS

11th February 2018 - Uncategorised

Dynamic websites are great, just install a database and some scripts and deliver a multitude of magical pages to your visitors, including realtime data merged into a seemingly common (garden) webpage. Astound them with JSON callbacks to live database records and write the pages with embedded table information and results of callbacks from webservices all other the place.

Le sigh, it’s great.

It’s a bit, well, overboard for a site sometimes, and wouldn’t it be grand to be able to show a simple web page without all the fancy hoo-haw.

20 years ago (creak) you’d just hand code HTML. Bah! The bad old days!

Well, we’ve moved on a tad now, and preprocessing, transpiling and cross-language compilation are all the rage.

These, so-called, Static Site generators, are ways for editors and content creators to add content to their sites using a very simple markup language. The markup languages vary according to the Static Site generator you use, but they consist of simple tags to denote paragraphs, links, images and formatting. Much simpler than HTML and often can be used alongside source control repositories like git to automate the whole thing.

All’s well and grand, you just spin up Node, Go, or another language engine and point it at your content, which template it uses and hit go. It then generates your site and can host it.

That’s where we start to have issues, if you’re a lowly Microsoft Dev working on IIS. You see generally only one webserver can listen to a port, so if you have IIS installed you can’t really also run another webserver as they’ll both want to listen on port 80.
To get around this, you’d often have a shell service sitting on port 80, which then proxies to other non-standard ports on your server.

What i am going to do here is use IIS as the forwarding site and have a non-standard port used by my Static Site generator, 8082.

Any requests coming in for my static site on port 80, for the particular web address will be forwarded to port 8082. And returned the same way, and people accessing the Static Site will be none-the-wiser.

Before we go into the ARR installation, let’s install a empty site then the Static Site Generator.

According to, Jekyll and Hugo are the current most popular, so I’m Go-ing to install Hugo, as, where my pun indicated, it uses the Go language to generate the sites.

Install the Go binaries (or the full .msi package if you wish), add the location of Go to your Environment path, then from a console, see if you’re installed by running your standard “go version”

With Go Installed, we grab Hugo from the compiled binaries at

Choose the Windows one that suits your environment (AMD64 for me), and download it to your server, then pop it somewhere like C:\Hugo\bin.

Create a folder, name it “StaticSite” and add three subfolders. The first subfolder will be where we copy the Hugo binaries, so call it “hugo-bin”, the second site will be the IIS default site, so call it “iis-default” and the third will be where we have the actual static site, so call that “static-site”.

Open up a command prompt and navigate to your hugo-bin folder and enter “hugo help” and you should see some blurb about the version, flags and whatnot.

Now, navigate to the directory directly underneath, by typing “cd ..”
From this point we can create the default hugo install by running “hugo-bin\hugo new site static-site”. This will create the standard hugo site in the static-site directory.

Now, to test the site, we spin up hugo with our non-standard port by going into the static-site directory and starting the hugo server by using “..\hugo-bin\hugo server -p 8082” (You could add Hugo to your environment path to make it a little easier, but more dangerous).

Browse to localhost:8082 on your server (you won’t be able to access it otherwise) in a browser and you’ll see… a blank page if your theme is duff. Otherwise you should see a theme without pages.

But that’s good, as it’s not a 404 😉

Stop the hugo server running and now we can add some content to see the magic!

But first we need a theme, so initialise a git repo in the static-site folder and run the following; “git submodule add themes/ananke” to pull in the ananke theme. Use another theme if you want.
Then, browse to the static-site folder and edit the config.toml file to add the line “theme = ananke”. We’re now using the ananke theme, or your downloaded theme.

In the command console, enter the following to create a new page under the content folder “..\hugo-bin\hugo new”

Hugos templating language is a markdown variant, so it’s fairly simple to pick up, or at least have a cheat sheet for.

Open up the static-site\content folder and edit the new page you created in the content folder.You will see it has a header with the title and a draft flag. This allows you to edit files as draft before republishing them, so you can spin up an instance of the hugo server in draft mode to see the in-progress page.

Add the following to the page

# Welcome

## Introduction
blah de blah

Run the following from your static-site root

..\hugo-bin\hugo server -p 8082 -D

This will start hugo in draft mode and you will see your page in the navigation when you browse to localhost:8082

You should see the theme with your page content.

Good good. Now to hook IIS up..

Next step is to create your website in IIS, ensuring that a new domain resolves to your site.

Point the new website to a basic html page, with the “iis-default” folder you created earlier. Add something like “This is IIS” to the page content, so we can immediately see when the routing is complete.

Add a hosts entry in your development PC to point your domain to IIS. Enter the same domain as a host header in IIS.
Browse to your domain, you should see the “This is IIS” message in the webpage.

We know we have IIS going to the default folder, and we still have the hugo server running, meaning that when we browse to localhost:8082 while on our server we see the hugo site.

Download and install the ARR extension.
What we want to do is proxy the site at 8082, to be served by the domain listening on port 80.

So, after you’ve installed the ARR, restart IIS manager and you will see a new entry, Server Farms.
Create a new Server Farm, call it “hugo static”.
In the next dialog, click “Advanced Settings” before adding a site.
Add your hugo site here, by adding a reference to “localhost”, edit its port in the advanced settings to 8082 and the host-header to localhost.
Click Finish then select “No” when IIS offers to create the routes.
Select your new farm, and select the Routing Rules.
Ensure that the “Use URL Rewrite…” selection is checked.
Click Apply (on the right)
Click “URL rewrite” under “Advanced routing”
Click “Add Rule”
Create a blank inbound rule, call it “hugostatic-in”, using : “Wildcards”, Pattern: “*”
Add a condition for the {HTTP_HOST} to match your domain.
Change the Action Type to “Route to Server farm”

Now, from your developer machine, browse to your domain, and you should see the Hugo site, rather than the iis-default page.
You may need to fiddle with your hugo theme to get the links correct, but the hard part here is done.

This is the same process if you want to host a node site also.

Alternatively, run hugo without the server parameter and it will publish your site to /public, which you can point iis to and remove the forwarding entirely. What a waste of time 😉