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:
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:
- 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 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.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
andCD_HOST
variables - Make sure Traefik config (
docker\traefik\config\dynamic\certs_config.yaml
) references the correct certificate and key files Create-jss-project.ps1
– features--layoutServiceHost
and--deployUrl
parameters ofjss setup command
src\rendering\scjssconfig.json
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 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!