Skip to main content


Tunneling out Sitecore 10.3 from a Local Machine Containers for a Global Access

Tunneling out Sitecore 10.3 from a local machine containers for a global access

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 typically set 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 currently serving 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

My cat enjoys high-spec hypervisor equipment

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

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

  1. Define a hostname and configure Sitecore to install with its subdomains.
  2. Generate a wildcard certificate for a domain name of the above hostname.
  3. 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 various DynDNS options that still required more effort than I was initially going to commit. But even worse – I am behind NAT, which means DynDNS is not much help here. Eventually, I remembered a specific class of tunneling software that serves precisely 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

For Sitecore to operate from outside, I must set it up so 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, 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.localhostcd.YourProject.localhostid.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:

  1. Init.ps1 – a block that makes and installs certificates (search by & $mkcert -install)
  2. Init.ps1 – a block that adds host file entries (search by Add-HostsEntry)
  3. Init.ps1 – a block that sets the environment variables (search Set-EnvFileVariable "CM_HOST")
  4. Up.ps1 – authentication using Sitecore CLI (search by dotnet sitecore login)
  5. Up.ps1 – final execution in the browser (search by Start-Process at the bottom of the file)
  6. .env file – replace CM_HOSTID_HOSTRENDERING_HOST and CD_HOST variables
  7. Make sure Traefik config (docker\traefik\config\dynamic\certs_config.yaml) references the correct certificate and key files
  8. Create-jss-project.ps1 – features --layoutServiceHost and --deployUrl parameters of jss setup command
  9. src\rendering\scjssconfig.json
  10. src\rendering\src\temp\config.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 the 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 will see Sitecore CM and Rendering Host in the browser with alternated domain URLs.

Now I can start LocalTunnel by requesting my sample subdomains:

lt --local-host --local-https --allow-invalid-cert --port 443 --subdomain identity
lt --local-host --local-https --allow-invalid-cert --port 443 --subdomain sitecore
lt --local-host --local-https --allow-invalid-cert --port 443 --subdomain rendering
lt --local-host --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!

Leave a Reply

Your email address will not be published. Required fields are marked *

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

Martin Miles

Martin is a Sitecore Expert and .NET technical solution architect involved in producing enterprise web and mobile applications, with 20 years of overall commercial development experience. Since 2010 working exclusively with Sitecore as a digital platform. With excellent knowledge of XP, XC, and SaaS / Cloud offerings from Sitecore, he participated in more than 20 successful implementations, producing user-friendly and maintainable systems for clients. Martin is a prolific member of the Sitecore community. He is the author and creator of the Sitecore Link project and one of the best tools for automating Sitecore development and maintenance - Sifon. He is also the founder of the Sitecore Discussion Club and, co-organizer of the Los Angeles Sitecore user group, creator of the Sitecore Telegram channel that has brought the best insight from the Sitecore world since late 2017.

More from this Author

Follow Us