Docker and LinkManager playing nicely…

Having started down the Docker road, I hit an interesting issue the other day. How do you get Sitecore to generate absolute links correctly when your site runs inside a container?

The issue…

After firing up some client code on a Sitecore v9.2 instance in Docker, code appeared to run ok, but URL generation wasn’t right. Two issues were apparant: Firstly, the site was configured to generate absolute URLs, but they did not include the correct port to work:

And secondly, when you tried to go to the Sitecore desktop and fire up Content Editor, it was broken:

What was going on here?

Research…

My initial thought was “I need to tell Sitecore about the odd port I’m using, so it can generate URLs correctly”. So off to Google I went. And I found a huge number of “why does Sitecore keep putting port 443 on the end of my URLs?” Stack Overflow questions, plus blog posts about that issue. But I did not find anything much about a situation where you actually want to add a port.

I did discover that Site Bindings can have port settings – but adding these just broke site resolution for me, causing the whole website to fall over.

I suspect I spent an hour banging my head against this, and rubber-ducking the issue with colleagues before I hit a breakthrough: Google threw up a post about configuring Sitecore when it’s sat behind a device that routes to non-standard ports, by my old chum Steve McGill.

And that made the whole thing click in my head:

The solution

The issue here is that under Docker, I am browsing to Sitecore at http://localhost:44001/ but internally the Docker network engine is remapping that request to http://localhost:80/ inside my container. Sitecore doesn’t know anything about port 44001 at all – and hence all my problems above!

So how do we fix this? Simple – and also explained by Steve’s post.

ASP.Net has a feature for deciding how it initialises the request context object that Sitecore receives whenever you make a request. By default, it’s initialised by the literal incoming request. So in this case, it sees the requested URL as http://localhost:80/ – but that request was actually forwarded from the external Docker port. So under the surface there’s actually an HTTP header that describes the original request:

And if we tweak ASP.Net’s config, it will initialise the request context using that data.

In the appSettings element of your web.config file, you add:

<add key="aspnet:UseHostHeaderForRequestUrl" value="true" />

to enable this behaviour. And with that done, your absolute URLs will start including the correct port:

And Content Editor will work again.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.