Curiosity Orchestrator
Many Studio instances.
One address.
The orchestrator runs each Studio instance as a Docker container and puts one address in front of them. It wakes a sleeping instance on the first visit and stops it again after an hour of no use.
06 · The visitor lands where they pointed
What it does
A Studio for every team, on one machine
Each instance keeps its own data and its own sign in. The orchestrator does the rest.
01
One address in front
A landing page lists the published instances. /acme/ and acme.example.com both reach the instance named acme, over HTTP and websockets.
02
Sleeps when nobody uses it
An instance with no traffic for an hour is stopped. Opening it starts it again, and the starting page takes you in when it is ready.
03
One console for all of them
Create, start, stop, restart and delete instances. Update their image, back up their data, read their logs and watch CPU, memory, network and disk.
04
On a host you control
It runs with Docker on your machine. Each instance keeps its data in its own Docker volume. HTTPS comes from your certificate, a self signed one or Let’s Encrypt.
Sleep and wake
An instance nobody uses stops, and wakes when somebody does
Idle time, keep warm and capacity are settings, not scripts. Pick a step to stop the drawing and read it.
- 01
It runs while it is used
Every request counts as activity, and a request in progress, an upload or a download, keeps the instance up. A tab left open does not.
- 02
Nobody uses it for an hour
After
ORC_IDLE_TIMEOUT_MINUTESwithout traffic, 60 by default, the orchestrator stops the instance. - 03
It sleeps
The stop is graceful: Studio saves its graph on the way down, so a stop can take up to 10 minutes. The data stays in its Docker volume.
- 04
A visit wakes it
Opening it in the browser shows the starting page, which starts the instance and keeps asking until it is ready.
- 05
It is running again
The visitor lands on the address they asked for. The idle clock starts again.
- 06
Or keep it warm
Keep warm holds an instance running for up to 7 days. It is a guarantee: one found stopped, after a crash or a reboot, is started again.
One address
The first word names the instance
A path or a subdomain, the same instance. Cookies and redirects are re-scoped to /{slug}/, so instances on one host do not overwrite each other’s sign in.
example.com/aviation/search
The instance aviation, at /search.
aviation.example.com/search
The same instance, at the same /search. The first label of the host names it.
example.com/ and www.example.com/
The orchestrator’s own landing page.
nothing-by-this-name.example.com/
The orchestrator again, because no instance has that name.
Subdomains need a wildcard DNS record and a certificate that covers it. Switch subdomain routing off and the path address is all there is.
Management console
One console, every instance
Password protected, at /#/manage. Everything you would do to a container by hand, with the usage beside it.
- Create, start, stop, restart and delete instances
- Update an image, or every outdated one at once
- Keep an instance warm for up to 7 days
- Back up, restore or reset an instance’s data
- CPU, memory, network and disk, per instance and for the host
- Container logs, the activity history and the effective settings
Fleet
Add machines when one is not enough
A central orchestrator manages nodes on other machines. Each node runs its instances exactly as a standalone one does, and keeps running them if the central goes away.
- 01
A node starts
Run the orchestrator with
ORC_ROLE=nodeon another machine. It prints an enrollment code and waits. - 02
The central approves it
Add it by address with the code, or let it join with a one time token. Every call after that is signed with a secret of its own.
- 03
Create an instance on a node
Pick a node for a new instance, or let the central choose the one with the most free memory.
- 04
One address for visitors
Visitors open
/{slug}/or{slug}.{host}on the central, which forwards to the node. - 05
Move it to another node
A move stops the instance, copies its data across and starts it on the other node, keeping what is left of a keep warm.
Install
Run it on your own machine
One command, then one with a password. The release is self contained. All it needs is Docker.
macOS · Linux
01 · Install
Downloads the latest release for your machine, checks its SHA-256 and unpacks it into ~/.curiosity/orchestrator. A launcher goes in ~/.curiosity/bin, and your shell profile gets that folder on its PATH. Docker is not installed for you.
curl -fsSL https://raw.githubusercontent.com/curiosity-ai/orchestrator/refs/heads/main/install.sh | sh
02 · Start it
Start it with a management password. Data goes to ./storage unless ORC_STORAGE names a folder, so set it for anything beyond a try out.
ORC_ADMIN_PASSWORD='choose-a-password' ORC_STORAGE="$HOME/.curiosity/orchestrator-data" curiosity-orchestrator
What you see
curl -fsSL https://raw.githubusercontent.com/curiosity-ai/orchestrator/refs/heads/main/install.sh | shInstalling the Curiosity Orchestrator (linux-x64) downloading v26.10.6452: https://github.com/curiosity-ai/orchestrator/releases/download/v26.10.6452/curiosity-orchestrator-26.10.6452-linux-x64.tar.gz sha256 verified installed /home/you/.curiosity/orchestrator launcher /home/you/.curiosity/bin/curiosity-orchestrator added /home/you/.curiosity/bin to PATH in /home/you/.bashrc The Curiosity Orchestrator v26.10.6452 is installed.Open a new terminal, or run this one first: export PATH="/home/you/.curiosity/bin:$PATH"Then start it with a management password (data goes to ./storage unless ORC_STORAGE says otherwise): ORC_ADMIN_PASSWORD='choose-a-password' ORC_STORAGE="$HOME/.curiosity/orchestrator-data" curiosity-orchestrator ORC_ADMIN_PASSWORD='choose-a-password' curiosity-orchestrator
Windows
01 · Install
Downloads the latest release, checks its SHA-256 and unpacks it into %USERPROFILE%\.curiosity\orchestrator. The folder is added to your user PATH. Docker Desktop is not installed for you.
irm https://raw.githubusercontent.com/curiosity-ai/orchestrator/refs/heads/main/install.ps1 | iex
02 · Start it
Start it with a management password. To upgrade later, stop it first: Windows locks the folder of a running program.
$env:ORC_ADMIN_PASSWORD = 'choose-a-password'; $env:ORC_STORAGE = "$HOME\.curiosity\orchestrator-data"; curiosity-orchestrator
What you see
irm https://raw.githubusercontent.com/curiosity-ai/orchestrator/refs/heads/main/install.ps1 | iexInstalling the Curiosity Orchestrator (win-x64) downloading v26.10.6452: https://github.com/curiosity-ai/orchestrator/releases/download/v26.10.6452/curiosity-orchestrator-26.10.6452-win-x64.zip sha256 verified installed C:\Users\you\.curiosity\orchestrator The Curiosity Orchestrator v26.10.6452 is installed.Start it with a management password (data goes to .\storage unless ORC_STORAGE says otherwise): $env:ORC_ADMIN_PASSWORD = 'choose-a-password'; $env:ORC_STORAGE = 'C:\Users\you\.curiosity\orchestrator-data'; curiosity-orchestrator $env:ORC_ADMIN_PASSWORD = 'choose-a-password'; curiosity-orchestrator
Docker
01 · The Dockerfile
The orchestrator also runs as a container, and needs the Docker socket to manage the instances’ containers. This builds an image from a release.
FROM mcr.microsoft.com/dotnet/runtime-deps:10.0
ARG VERSION
ARG RID=linux-x64
ADD https://github.com/curiosity-ai/orchestrator/releases/download/v${VERSION}/curiosity-orchestrator-${VERSION}-${RID}.tar.gz /tmp/orchestrator.tar.gz
RUN tar -xzf /tmp/orchestrator.tar.gz -C /opt \
&& mv /opt/curiosity-orchestrator-${VERSION}-${RID} /app \
&& rm /tmp/orchestrator.tar.gz
WORKDIR /app
ENV ORC_STORAGE=/data \
ORC_CONTAINER_ACCESS=network
VOLUME /data
EXPOSE 8080 443
ENTRYPOINT ["./curiosity-orchestrator"]
02 · The compose file
Next to it. This serves HTTPS with a self signed certificate. For Let’s Encrypt, the README has the settings.
services:
orchestrator:
build:
context: .
args:
VERSION: 26.10.6452 # a release from the GitHub releases page
RID: linux-x64 # linux-arm64 on an Arm host
image: curiosity-orchestrator
restart: unless-stopped
environment:
- ORC_ADMIN_PASSWORD=${ORC_ADMIN_PASSWORD:?Set ORC_ADMIN_PASSWORD}
- ORC_PUBLIC_ADDRESS=${ORC_PUBLIC_ADDRESS:-https://localhost}
- ORC_CERT_SELF_SIGNED=true
- ORC_PORT=443
- ORC_PORT_LOCAL=8080
- ORC_REDIRECT_TO_HTTPS=true
ports:
- "443:443"
- "80:8080"
volumes:
- orchestrator-data:/data
- /var/run/docker.sock:/var/run/docker.sock
stop_grace_period: 1m
volumes:
orchestrator-data:
What you see
ORC_ADMIN_PASSWORD='choose-a-password' docker compose up -dOpen https://localhost/#/manage and sign in as admin.
To upgrade, run the script again. It replaces the program and leaves your data, which lives under ORC_STORAGE. Settings, all optional: ORC_VERSION for a release other than the latest, ORC_INSTALL for another folder, ORC_NO_MODIFY_PATH=1 to leave your PATH alone.
Your first instance
From install to a running Studio
- 01
Start it
Run the orchestrator with a password. It listens on port 8080 and keeps its data in
./storageunlessORC_STORAGEsays otherwise. - 02
Create an instance
Open
localhost:8080/#/manage, sign in asadminand create an instance namedacme. The first time, it pulls the Curiosity image, which takes a while. - 03
Open it
Go to
localhost:8080/acme/, oracme.localhost:8080. Browsers resolve*.localhostto your own machine.
Operations
What you would otherwise write scripts for
HTTPS, backups, updates and limits are part of the console and its API.
HTTPS
Your own certificate, a self signed one, or certificates from Let’s Encrypt. They renew 30 days before expiry, and each instance gets one for its subdomain.
Backups
Download an instance’s data as a .tar.gz, restore it into the same or another instance, or reset it to empty. A restore is checked in full before anything is deleted.
Updates
Update an instance’s image one at a time, or every outdated one at once. The data stays in its volume.
Scripting
Set ORC_API_TOKEN and the management API takes a bearer token, so a backup is one curl call.
Capacity
Set the most instances that may run at once. Waking one on a full host stops the one used least recently, if nobody is using it.
Logs and usage
Container logs with follow, filter and download. CPU, memory, network and disk per instance and for the host, with history.
Security
What to know before you expose it
The README says where the trust boundaries are. So does this page.
01
Console sign in
The session cookie is HttpOnly and SameSite strict, and failed sign ins are throttled. The API token grants the same access as the console.
02
A host of its own for the console
Instances on paths share the orchestrator’s origin. Where instance administrators are not fully trusted, set ORC_MANAGEMENT_HOST and the console answers only there.
03
Subdomains give each instance an origin
Opening an instance on its subdomain keeps its pages apart from the console and from the other instances.
04
The Docker socket is root equivalent
The orchestrator needs it to manage containers, and ORC_STORAGE holds each instance’s administrator password. Protect both like secrets.
FAQ
Questions about the orchestrator
What does the orchestrator need to run?
Docker on the host. The releases are self contained, so no .NET installation is needed. The install script covers Linux, macOS and Windows, and warns you when it cannot find Docker.
How is it different from running Studio in Docker myself?
One container is one container. The orchestrator is for several: it puts them behind one address, starts and stops them as they are used, updates their images, backs up their data and shows their usage.
What happens to an instance’s data when it sleeps?
It stays in the instance’s Docker volume. Stopping is graceful, because Studio saves its graph on the way down, so a stop can take up to 10 minutes. Updating the image or changing limits re-creates the container and never touches the volume.
Does a background request wake a sleeping instance?
No. Opening it in the browser wakes it. A background request, such as an API call or a stale tab polling, gets a 503. A tab left open does not keep an instance awake either.
How do I keep an instance running?
Keep it warm for up to 7 days. It is a guarantee: a kept warm instance that is found stopped, after a crash or a reboot, is started again. Stopping it from the console clears it.
Can I use my own domain and certificate?
Yes. Provide a certificate file, let the orchestrator generate a self signed one, or let Let’s Encrypt issue and renew them. Subdomain addresses need a wildcard DNS record and a certificate that covers it. With subdomain routing off, only the path address is served.
Can several machines serve one set of instances?
A central orchestrator can manage nodes on other machines and serve all their instances from one address. It calls each node by its address, so a node behind NAT is not supported yet.
Can I script it?
Yes. Set ORC_API_TOKEN, 24 characters or more, and send it as a bearer token. The management API then does what the console does, including backup and restore.
Your data. Your infrastructure.