Skip to main content

Docker container

This guide runs a plain, non-secured Zaris cluster as Docker containers: four nodes from a single image, all sharing one config file, discovering each other by service name. It corresponds to the docker/ directory in the Zaris repository and uses the attach deployment model.

Use this for local development and evaluation. For a secured cluster with mutual TLS and token authentication, see Docker Compose (secured); for orchestration, see Kubernetes.

How the node image works

Every node runs the same image, clustron-zaris-node:local, built from docker/Dockerfile.node. The image publishes Clustron.Zaris.Host onto the .NET 8 ASP.NET runtime and starts it with a fixed entrypoint that reads a mounted config file:

dotnet Clustron.Zaris.Host.dll --ConfigPath /config/clustron.json

Three facts define how a node behaves in a container:

  • One image, one config. Every container mounts the same config/clustron.json at /config/clustron.json (read-only). The config lists all nodes under nodes[], each with its id, host, clusterPort (7811), and clientPort (7861).
  • CLUSTRON_NODE_ID gives each container its identity. A node learns which of the configured nodes it is from the CLUSTRON_NODE_ID environment variable, set per service and validated against nodes[]. This is the entire per-container identity mechanism.
  • Peers find each other by service name. The host values in the config are the Compose service names (zaris-n0..zaris-n3). Docker's built-in DNS resolves them on the shared bridge network — no external discovery service is needed.

The store is in-memory, so no data volume is required. Each container has its own network namespace, so all nodes share the same ports: the client port 7861 (where clients connect) and the cluster port 7811 (intra-cluster peer traffic).

Prerequisites

Confirm the following before you start:

  • Docker and Docker Compose installed and running (Docker Desktop on Windows works).
  • The Zaris repository checked out locally. The docker compose commands below run from its docker/ directory.

Build the node image

The Dockerfile's build context is the repository root, so build from there and point at the Dockerfile under docker/. From the repository root, run:

docker build -t clustron-zaris-node:local -f docker/Dockerfile.node .

Compose also builds the image on demand (--build), so this explicit step is optional but useful for confirming the image builds cleanly.

Run the plain node-only cluster

The docker-compose.yml file defines four node services — zaris-n0 through zaris-n3 — on a bridge network named zaris. Each service sets its own CLUSTRON_NODE_ID, mounts the shared config, and publishes its client port to a distinct host port in the 1786x range so it does not clash with a native Windows cluster on 7861.

  1. From the docker/ directory, build the image and start the four nodes:

    docker compose up --build -d
  2. Watch the nodes form a cluster, and confirm they report healthy once their client ports are listening:

    docker compose logs -f zaris-n0
    docker compose ps
  3. When you are done, tear the cluster down:

    docker compose down

This stack is node-only — it runs the store engine with no Management Service and no Web Console. Each node's client port maps to the host as follows:

ServiceContainer client portHost port
zaris-n0786117861
zaris-n1786117862
zaris-n2786117863
zaris-n3786117864

The cluster port 7811 stays internal to the zaris network.

note

The cluster advertises peer endpoints by their in-network service names, so the most reliable way to use the store is from inside the zaris network. A host-mapped client port (localhost:17861) reaches one node directly, but a host-side client may be handed an in-network peer address it cannot resolve. Run clients as containers attached to the zaris network, or use the manager stack below.

Run with a manager and Web Console (attach)

To get a Web Console and a single, coherent cluster view, use the attach stack instead. docker-compose.attach.yml adds one Management Service container (clustron-zaris-machine:local) that runs with ZARIS_MGMT_MODE=attach: it observes the four orchestrator-run nodes and adopts them with Register-ZrStore — it never forks a node.

The up.ps1 script wraps this end to end — it resets any previous stack, builds, starts the four nodes plus the attach manager, waits for health, and registers the running cluster as a store.

  1. From the docker/ directory, bring up the attach stack and adopt the cluster:

    ./up.ps1

    To reuse the existing image without rebuilding, add -NoBuild; to keep existing data volumes, add -KeepData.

  2. Alternatively, run Compose directly and register the store yourself:

    docker compose -f docker-compose.attach.yml up --build -d

When the stack is up, the control plane is published to the host:

  • Web Consolehttp://localhost:18101
  • Management APIhttp://localhost:17801
  • Nodes (client)localhost:17861..17864

Drive the cluster from the Console, or from the AdminShell inside the manager container:

docker exec -it zaris-manager pwsh
# then: Get-ZrStore, Get-ZrNode, ...

Tear the attach stack down with ./down.ps1, or docker compose -f docker-compose.attach.yml down -v.

Scale the node count

Node membership is declared in the config, so scaling means editing two files in step. To change the node count:

  1. Add or remove entries in nodes[] in config/clustron.json, keeping each node's id, host, clusterPort, and clientPort consistent.
  2. Add or remove matching services in the Compose file, each with its own CLUSTRON_NODE_ID that references a nodes[] entry.
  3. Recreate the stack so the containers pick up the new config.

Next steps