Skip to main content

Running the node

There are two supported ways to run a Demos node:
  • Track 1 — Docker Compose (recommended). Single-command bring-up of the full stack: node + Postgres + TLSNotary + monitoring. Pick this unless you have a specific reason not to.
  • Track 2 — bare metal ./run (advanced). Node binary runs natively on the host via Bun; only Postgres lives in a sidecar container managed by ./run. Pick this for core development, kernel-level debugging, or TUI-driven operation.
Both tracks start from the same repo (git clone https://github.com/kynesyslabs/node.git) and the same .env file (cp .env.example .env). They differ only in where the node binary and its dependencies live. For the full install walkthrough see INSTALL.md; for variable-by-variable settings see Node configuration.

Prerequisites

  • Docker 20.10+
  • The docker compose v2 plugin (with a space — the legacy hyphenated docker-compose Python script is not supported)
  • git

Start the node

From the repo root:
The first run pulls images and builds the node container, which can take a few minutes. Subsequent starts are near-instant. When the stack is healthy:
  • Node RPC: http://localhost:53550 (try curl http://localhost:53550/info)
  • Grafana: http://localhost:3000 (default admin / demos)
  • Prometheus: http://localhost:9091

First boot: identity generation

On the very first start the node entrypoint:
  1. Generates a fresh ed25519 keypair if .demos_identity does not exist in the demos_node_state volume.
  2. Writes the private key into the volume at .demos_identity.
  3. Writes the public key to a publickey_<timestamp> file alongside it and prints it in the container logs.
Tail the logs to grab your public key:
Your identity now persists across docker compose down / up cycles. It is destroyed by docker compose down -v — back it up first (see Backing up and restoring a node).

Common operations

State persists in named Docker volumes prefixed demos_: The demos_ prefix is set explicitly in docker-compose.yml, so volume names are stable regardless of the directory you ran compose from.

Compose profiles

COMPOSE_PROFILES in .env controls the optional services. The defaults are tuned for local development.

Going public

Before joining a real Demos network from a machine that other peers should reach:
  1. Set EXPOSED_URL in .env to your reachable address (public IP or DNS), not localhost.
  2. Open inbound TCP for RPC_PORT (53550), OMNI_PORT (53551), and 7047 (TLSNotary, if enabled) on your firewall before advertising the public URL.
  3. Seed demos_peerlist.json with bootstrap peers from the team — see Joining the testnet using a custom genesis.
Do not expose 5432 (Postgres), 9090 (node metrics), 9091 (Prometheus), or 3000 (Grafana) to the public internet. Keep them behind your firewall or VPN.

Track 2: Bare metal ./run (advanced)

In Track 2 the node binary runs natively under Bun, and only Postgres lives in Docker (as a sidecar managed by ./run).

Prerequisites

  • Docker (still needed for the Postgres sidecar)
  • Bun (via Mise or the direct installer)
  • Rust (required by ./scripts/install-deps.sh to build wstcp)
  • A .env with the bare-metal overrides:
The full prerequisite walkthrough lives in INSTALL.md — Track 2.

Start the node

That spins up the Postgres sidecar (host-mapped on 5332), runs the node natively, and opens the TUI. Stopping the node with Ctrl+C (or Q in the TUI) shuts the sidecar down too.
./run at the repo root is a thin wrapper that forwards to scripts/run (the actual implementation). Always invoke ./run from the repo root — never call scripts/run directly. The wrapper exists so the legacy command path keeps working.

First boot: identity generation

The very first ./run:
  1. Generates a fresh ed25519 keypair if .demos_identity does not exist.
  2. Writes the private key to .demos_identity in the repo root.
  3. Writes the public key to publickey_<timestamp> and prints it on the console.
Press Ctrl+C (or Q in the TUI) to stop, then edit .env / demos_peerlist.json before restarting. Set tight permissions on the identity file:

./run flags

Examples:

TUI controls

By default ./run launches a terminal UI with tabs for Core, Network, Chain, Consensus, and others. Disable the TUI with ./run -t or ./run --no-tui if you prefer plain log output (useful in tmux, CI, or when piping to a file).

Verify the node is running

In a separate terminal:

Stop the node

Press Ctrl+C (or Q in the TUI) in the ./run terminal. To stop the Postgres sidecar manually:

Reset chain state without losing identity

If you are connected to peers, the node will resync from them. If you are running solo, the chain restarts from the genesis block.

Bare-metal troubleshooting