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?
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?
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 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.
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.