Docker
For: cluster operators.
Use the supplied Compose layout to start the deployment. Preserve its keys and data volumes when replacing containers.
Two ways to run Orchestrator Zero with Docker, both from images you build locally (no official images are published yet):
- The quickstart, one container with a dev server, the console, a node and a sample plugin, to try it.
- Compose, for a small team on one machine: PostgreSQL, one server in cluster mode and one node, each in its own container with its own volume. More nodes join from other machines.
Try it in one command
Building the image currently requires access to the private repository. Public source downloads and official images are coming soon. Build the image once, from your checkout:
make image-quickstart # orchestrator-zero:quickstart, built locally and never pushed
and run it:
docker run --rm -p 8443:8443 orchestrator-zero:quickstart
It starts a dev server, joins a node to it, installs the sample plugin from examples/greeter, runs a first job, and prints where to sign in:
Orchestrator Zero is running.
Web UI https://localhost:8443
User admin
Password lZDqnGomjNqVdXWNxiW6sZVr
The certificate comes from the cluster's own CA, so the browser asks you to accept it once.
A first job ran on the node: "Hello, quickstart! (from 1f0c2a7e9b3d)"
Everything the node needs is in the image: uv, Python, the runtime and the sample plugin's packages. The container starts in about 15 seconds and needs no network. The CLI is in the container too:
docker exec -it <container> oz0 node list
docker exec -it <container> oz0 job run --task-queue oz0.default --workflow HelloWorkflow --input '"you"'
The container's data, the dev cluster with its keys, lives in /var/lib/oz0. To keep it when the container goes, give it a named volume, which Docker fills with what the image holds there the first time:
docker run -d --name oz0 -p 8443:8443 -v oz0-quickstart:/var/lib/oz0 orchestrator-zero:quickstart
The quickstart is a dev server on SQLite with its node in the same container: for trying, demos and plugin development on one machine, not for a team's work or nodes on other machines. For those, use compose.
Compose for a small team
deploy/compose/compose.yaml runs a cluster with one server:
| Service | What |
|---|---|
postgres | PostgreSQL 16, its data in the volume postgres; healthy when it takes connections over TCP, so not during the first start's temporary server |
init | runs once per up: makes the master key and the admin's password in the volume secrets the first time, then server init --exist-ok, which creates the cluster once and afterwards checks that the key still unseals it |
server | server start in cluster mode: management, the edge and Temporal; healthy when its edge is ready (oz0 server healthcheck). Its erasure ledger is in the volume ledger, apart from the database |
token | runs once per up: a join token for one use, while the node has not joined |
node | joins once with that token, then keeps its identity, uv, Python and runtime in the volume node |
Build the images and set a password for PostgreSQL:
make images IMAGE_TAG=local
cp deploy/compose/.env.example deploy/compose/.env
sed -i "s/^OZ0_POSTGRES_PASSWORD=.*/OZ0_POSTGRES_PASSWORD=$(openssl rand -hex 24)/" deploy/compose/.env
Start it, and read the admin's password:
docker compose -f deploy/compose/compose.yaml up -d --wait
docker compose -f deploy/compose/compose.yaml exec server cat /oz0/secrets/admin-password
Sign in at https://<this machine>:8443 as admin. The CLI works from the server's container with the operator credentials init made:
docker compose -f deploy/compose/compose.yaml exec -e OZ0_CONTEXT=/oz0/secrets/operator/context.json server oz0 node list
Back up the master key now and keep it somewhere else: without it the cluster's CAs and secrets cannot be unsealed. Backups of the database need it too.
docker compose -f deploy/compose/compose.yaml cp server:/oz0/secrets/master.key ./oz0-master.key
.env holds the settings: OZ0_TAG (the images' tag), OZ0_POSTGRES_PASSWORD, OZ0_CLUSTER_NAME, OZ0_HISTORY_SHARDS (64; it can never change), OZ0_PUBLIC_HOST (the name other machines reach this one at, for the server's certificate), OZ0_PUBLISH_IP and the three ports, and OZ0_NODE_NAME.
docker compose down and up again keep everything: init finds the cluster, and the node comes back as itself without joining again. down -v removes the volumes, and with them the cluster. Back up the volume ledger apart from the database: a restore of an older backup applies again the erasures it records.
More nodes
Nodes on other machines join the edge on ports 7443 and 7233 with the console's Add nodes command, and run there as services. Set OZ0_PUBLIC_HOST to the name they reach this machine at, and restart the server (docker compose up -d), so that its certificate names it.
The command in the console names the server's address inside Docker's network (such as https://172.18.0.3:7443), which other machines cannot reach: replace it, both times it appears, with https://<OZ0_PUBLIC_HOST>:<OZ0_EDGE_API_PORT>. The node keeps using the address it joined through, and reaches Temporal at the same host on port 7233, the port the edge reports: for nodes on other machines, keep OZ0_EDGE_TEMPORAL_PORT at 7233.
When the team grows
Compose runs one server on one machine. For two or more servers, an external PostgreSQL and backups on a schedule, use the Helm chart or run the servers yourself.