I am experiencing an urgent request to prepare a Sitecore instance for the test of some external tools our prospect partners making demos for us. In good times, I’d, of course, spin up a proper PaaS / Kubernetes environment, however, for my particular task that would be serious overkill, I occasionally don’t get access to any of any cloud subscription, and what is much more important – stand short of time! The deadlines for such tasks are set typically as “yesterday”, so I started thinking of potential “poor man’s deployment” architecture.

Like many developers do, I also have a “server in a wardrobe“, however, that is not a retired laptop but a proper high-speck machine that currently serves me as a hypervisor server plugged by a gigabit Google Fiber connection. My cat loves spending time there, and I am generally OK with that given she does not block the heat sink vents output:

My cat enjoys high-spec hypervisor equipment

This server runs on ltsc2022 kernel, which provides me additional performance benefits, as I wrote about in a previous post of running 10.3 in Process Isolation mode. So why not re-use the codebase from that same containerized Next.js starter kit for the sake of PoC?

The next question comes of how do I make it accessible from the outer global internet so that people making demos can login from where they are and work with Sitecore as they would normally do. Typically, to make that happen I need to undertake three steps:

Define a hostname and configure Sitecore to install with its subdomains.
Generate a wildcard certificate for a domain name of the above hostname.
Make required DNC changes to change A-record and subdomains to point public IP of that machine.

But wait a bit, do I have a public IP? Sadly, I don’t, therefore, start looking for a variety of DynDNS options which still required more effort than I initially was going to commit into. Eventually, I remembered a specific class of tunneling software that serves exactly that purpose. From a wide range, LocalTunnel appeared to be the most promising free-to-use solution that some folks use to proxy out their basic sites for demos.

Looking at its features it looks very much attractive:

it is totally free of charge
does not require any registration/tokens
ultrasimple installation with npm
because of the above, it potentially can tunnel directly into containers
gives you an option of a temporal claiming subdomain, if one is available
allows mapping invalid SSL certificates

The typical installation and execution are ultra-simple:

npm install -g localtunnel
lt –port 8080

After the second command, LocalTunnel responds with a URL navigating which will tunnel your request to port 8080 of the host machine it was run at.

But how do I apply that knowledge to a complicated Sitecore installation, given that most of the Sitecore services in containers are behind Traefik, which also serves SSL offload point? In addition, the Identity Server requires a publically accessible URL to return the successfully authenticated request.

The more advanced call syntax looks as below:

lt –local-host HOST_ON_LOCAL_MACHINE –local-https –allow-invalid-cert –port 443 –subdomain SUBDOMAIN_TO_REQUEST

Basically, for Sitecore to operate from outside I must set it up in a way that external URLs match those URLs run locally at the host where LocalTunnel runs. With the above command, if a subdomain request is satisfied, it will be served by the URL https://SUBDOMAIN_TO_REQUEST.loca.lt which leads to HOST_ON_LOCAL_MACHINE on port 443.

So, in a headless Sitecore we have four typical parts running on subdomains of a hostname served by a wildcard certificate:

Content Management (aka Sitecore itself)
Content Delivery
Identity Server
Rendering Host

OOB they are served by default with something like cm.YourProject.localhost, cd.YourProject.localhost, id.YourProject.localhost and www.YourProject.localhost correspondingly. In order to match HOST_ON_LOCAL_MACHINE to SUBDOMAIN_TO_REQUEST for the sake of this exercise, I choose the following hostnames for installation:

The scripts that create Next.js StarterKit Template and Init.ps1 don’t modify all the required hostname changes, so just in case you’ll do it manually (recommended), I will list some of the locations for the changes:

Init.ps1 – a block that makes and installs certificates (search by & $mkcert -install)
Init.ps1 – a block that adds host file entries (search by Add-HostsEntry)
Init.ps1 – a block that sets the environment variables (search Set-EnvFileVariable “CM_HOST”)
Up.ps1 – authentication using Sitecore CLI (search by dotnet sitecore login)
Up.ps1 – final execution in the browser (search by Start-Process at the bottom of the file)
.env file – replace CM_HOST, ID_HOST, RENDERING_HOST and CD_HOST variables
Make sure Traefik config (dockertraefikconfigdynamiccerts_config.yaml) references the correct certificate and key files
Create-jss-project.ps1 – features –layoutServiceHost and –deployUrl parameters of jss setup command
srcrenderingscjssconfig.json
srcrenderingsrctempconfig.js

It may be a case, that you miss some settings and some containers would report “unhealthy” status. For quick troubleshooting this I’d recommend temporarily disabling health checks and returning 0 status code:

test: [“CMD”, “powershell”, “-command”, “exit 0”]

This trick allows docker-compose to reach Traefik execution so that you’ll have a routing in action to navigate into faulty containers and investigate the actual cause of an issue. Just don’t forget to return Heathchecks back upon completion!

Upon the successful completion of the whole installation steps and you see Sitecore CM and Rendering Host in the browser with alternated domain URLs.

Now you can start LocalTunnel:

lt –local-host identity.loca.lt –local-https –allow-invalid-cert –port 443 –subdomain identity
lt –local-host sitecore.loca.lt –local-https –allow-invalid-cert –port 443 –subdomain sitecore
lt –local-host rendering.loca.lt –local-https –allow-invalid-cert –port 443 –subdomain rendering
lt –local-host delivery.loca.lt –local-https –allow-invalid-cert –port 443 –subdomain delivery

On the first run from outside it may show you a notification screen that LocalTunnel serves a given URL, and with relatively good piing, that’s it.

I briefly tested it and it works well: no SSL issues, Experience Editor runs and allows to bring changes, then publishes them correctly so that they get reflected while browsing Rendering Host. All seems to work well and as expected!

Hope you find this helpful and potentially save some time doing your own showcases or presentations!