Skip to content

Stand up a demo server

A demo is a configured client example. Somebody trying Helix should be able to load a scenario, watch the optimiser work, and then look at how that client was configured — the domain file, the map, the scenarios. So a demo instance is not a sealed container: it is the client’s repo, mounted read-only, with the built client dropped into it.

That leaves one question, and this page is the answer to it: a demo server has no repo. It gets one from the release, which carries it.

helixctl release builds four client forms. Ordered from most airgapped to least:

--aswhat it istaken in with
studiothe client, its core pin and the repo’s own source — never a production sitehelixctl import
setcore image + bundle + launcher + pin, in one tar — a full airgap for productionhelixctl install
bundlethe client alone, for a node already on the core it was built againsthelixctl import
imageone image from a registry, everything baked inhelixctl pull

studio is the one a demo server and a tuning lab run, and it is the only form that carries source. That is a property of the form rather than a switch on another one, which is what keeps source out of the three that reach production.

Terminal window
cd Demos/<DEMO> && ./helix/runtime/helixctl release --as studio
# -> helix-<client>-studio-<version>.tar

Inside it, beside client/ and helix-config/, is a source/repo.bundle — a git bundle of the repo’s history at the commit the manifest records. So one file resolves everything the instance serves:

Terminal window
./helixctl <CLIENT> start demo helix-<client>-studio-<version>.tar

That one command pins and obtains the core the artefact names, restores the repo from inside it, places the built client into the restored tree, and runs a node on it. There is nothing to keep in step, because there is only one file naming every part.

Nothing reaches the network, and no credential is involved. There is deliberately no second way to get the repo — two ways to obtain one tree are two ways for it to differ, and the other one needed an access token or a deploy key. A release that carries its source is self-contained; one that does not is refused by name.

In a client repo the same start type takes no argument at all — it mounts the working tree you are standing in. Naming an artefact is what a machine with no repo does instead.

Terminal window
./helixctl <CLIENT> start demo # the repo you are in
./helixctl <CLIENT> start demo /path/to/repo/helix # a tree already on this machine
./helixctl <CLIENT> start demo helix-hra-studio-0.2.15.tar # restore the repo from the release
./helixctl <CLIENT> start tuning helix-hra-studio-0.2.15.tar # the same, as a Laboratory

demo and tuning, and the one thing between them

Section titled “demo and tuning, and the one thing between them”

Both mount the client repo and build nothing — they are the same kind of node, and a studio artefact serves either. What separates them is whether the container works on the tree itself or on a copy of it:

demotuning
the repoits own copy, made inside the containerthe actual tree
writableyes, within the sessionyes, and it persists
saves survive the containernoyes
how many at oncemany, each with its own copyone
credentialsany email, no passwordfirst name typed owns it

So a demo visitor can tune the domain, run the Laboratory and save a run file — all of it real, all of it gone when their container goes, and none of it able to touch the host’s tree, which is mounted read-only purely as the source of the copy. A tuner gets the same instance on the actual tree, so what they save stays and can be committed: storage/source is a real git checkout.

That is also why the release form is called studio rather than demo — the same artefact stands up a public demo on one machine and a client’s tuning lab on another.

Two things:

  1. A container runtime — podman (≥ 4) or docker, as any Helix node needs.
  2. git — to restore the bundle. It is a local operation; nothing goes to a remote. helixctl check reports it, as does a machine’s card in Mission Control.

Nothing else. No credential, no deploy key, no registry login and no network access to your repo host. No node, no npm, no client toolchain, no SDK fetch either: the built client comes out of the artefact and the source comes out of the same artefact.

Terminal window
# 1. The core and the launcher, from a release set
tar xf helixcore-release-<core>.tar && cd helixcore-release-<core>
./helixctl install --home demo # -> ~/HelixRuntime/demo/
cd ~/HelixRuntime/demo
# 2. Take the studio release in. Devops puts it in staging/ (usually a symlink to the release
# area it was built in), and this account pulls it — a release is never pushed at you.
./helixctl import # lists what is there to take
./helixctl import helix-hra-studio-0.2.15.tar
# 3. Start it. No key, no login, no network.
HELIX_PUBLIC_HOST=<this machine's address> ./helixctl HRA start demo helix-hra-studio-0.2.15.tar

The first start restores the repo; every later one finds the commit already there and starts immediately. The tree lives at storage/source beside the node’s other state, and you can read it, git log it and git diff in it — it has the repo’s real history, which is the point of it being a repo rather than a copy.

demo is built for concurrency: each instance takes a unique container name, its own port, a fresh tmpfs world and its own copy of the repo, all of which die with the container. The restored tree on the host is read-only to every one of them — it is only the thing the copies are made from — so instances cannot collide with each other or reach anything outside themselves.

Nothing a visitor does in a demo survives it, and nothing a visitor does can reach the host’s source.

Import the new artefact and start on it. The core comes with it:

Terminal window
./helixctl import helix-hra-studio-0.2.16.tar
./helixctl HRA start demo helix-hra-studio-0.2.16.tar

If the new release is at a different commit, that commit is fetched from the new artefact into the tree already there — not restored from scratch. Instances already running are unaffected; they finish on what they started with.

Each of these is a prerequisite or a fault at the source, and each says which:

What it saysWhat happened
git is not installedinstall it, then start again. No credential is needed — only git itself
<artefact> carries no source, so there is no repo to serveit is a plain --as bundle release. Build it --as studio, or name a repo path instead
<artefact> disagrees with itselfits manifest names one commit and its source bundle holds another — the two halves were not built together. Build it again
the source bundle … could not be readthe artefact was corrupted or truncated in transit. Import it again
<artefact> records no commitit was not built from a git checkout at all
holds no helix/customthe restored tree is not a Helix client repo
has uncommitted changes, and … is at a different commita tuning session saved work in storage/source that a newer artefact would discard. Commit or stash it there first

Pushing does not come into it. A studio artefact carries the commit rather than referring to it, so a release built from work that was never pushed serves perfectly well. What release does warn about is an uncommitted worktree: the client is built from your working tree, so the SPA will be the edited build — but scenarios reach the instance only from the commit, so an uncommitted scenario is simply absent.

studio is the word because the use is wider than a public demo. The same artefact stands up a tuning lab: a client’s own people experimenting against the real configuration in the Spiral Laboratory, with the repo there to read and the scenarios there to run. That is also why there is no size limit on the source it carries — a big repo is a legitimate thing to want in a lab.

For a server facing the public — a picker on a website, one instance per visitor, seats, idle reaping, lead capture — that is the demo orchestrator, which drives exactly the command above once per session. It ships inside the core image at /app/demoOrchestrator and has its own README there.