Skip to content
Tenzro
Documentation menu
Build and operate

Deployment

Run tenzro-node on Network 1: roles, hardware-rooted identity, ports, running as a service, containers, orchestrators, light nodes and monitoring.

Every Tenzro operator runs the same binary, tenzro-node. One node can take any set of roles under one identity and one stake: validator, RPC provider, model (AI) provider, compute, storage, database, TEE, training. This page covers how to deploy it. For which role to pick and what each earns, see Operators and roles.

Install

Pre-built binaries for Linux and macOS are on the downloads page. The tenzro CLI is also on Homebrew:

bash
brew tap tenzro/tap && brew install tenzro

To build from source you need a Rust toolchain plus clang, cmake, protoc, pkg-config and OpenSSL:

bash
git clone https://github.com/tenzro/tenzro-network
cd tenzro-network
cargo build --release -p tenzro-node -p tenzro-cli
# binaries: target/release/tenzro-node and target/release/tenzro

The node runs on Linux and macOS, on x86-64 and ARM64. Model providers build with the accelerator backend for their hardware as a cargo feature: cuda, rocm, metal (on by default on Apple Silicon), vulkan, sycl, opencl and others. With no feature the node serves on the CPU. See Hardware discovery.

Hardware-rooted identity

A node's identity is rooted in hardware. Its signing keys are derived from the machine's TPM 2.0 or Secure Enclave on demand, used in memory and wiped; there are no key files to copy, back up or leak.

  • Validators need a TPM 2.0 or a Secure Enclave. Any machine with one can run a validator. Consensus votes are signed with an in-memory session key that the hardware certifies once per epoch. See Hardware-rooted keys.
  • Autonomous operation needs the same. tenzro setup --operator autonomous is only offered on a machine that can root its own keys.
  • Machines without a chip can still serve, as a sub-identity of a machine that has one. Adopt the machine from the owner with tenzro node own adopt, then run the owner with --provide-identity-to <did>=<peer-address> and --identity-serve-addr, and start the chipless machine with --identity-owners <owner-rpc-url>. List more than one owner so the machine keeps its identity when one is down. Use addresses on a private network (a WireGuard or tailnet address), because the owner authenticates the machine by the address it connects from.

Check what a machine offers before you start:

bash
tenzro hardware
tenzro tee detect

Guided setup

tenzro setup walks through joining Network 1, bootstrapping a local network or joining a private one, and writes the configuration and service unit for you:

bash
tenzro setup --path network --mode validate --roles validator --yes
tenzro setup --path network --mode provide --roles ai,storage --access on-demand,subscription

Run the node

bash
tenzro-node \
  --roles validator,ai \
  --data-dir /var/lib/tenzro \
  --rpc-addr 0.0.0.0:8545 \
  --web-addr 0.0.0.0:8080
  • Omit --boot-nodes and the node finds Network 1 bootstrap peers through DNS, so a fresh install joins with no further flags. Pass explicit multiaddrs to choose your own peers, or --boot-nodes "" to run isolated.
  • Run the exact binary version and genesis the network runs. State is deterministic; a different binary or an edited genesis produces a different state root, and your blocks are rejected.
  • A new validator joins as a non-voting node that validates and syncs. It proposes and votes once it has bonded and has been admitted at an epoch boundary. See Validator lifecycle.
  • Every listener binds to loopback by default. Nothing is reachable off the machine until you pass an address such as --rpc-addr 0.0.0.0:8545.
  • TENZRO_DATA_DIR sets the data directory once for both the node and the CLI.

Ports

PortServiceExpose
9000 TCP and UDP (QUIC)Peer-to-peerAlways, for validators
8545JSON-RPC and OpenAI-compatible routesRPC and model providers
8080Web API and /metricsHealth checks; metrics to your monitoring only
3001MCPIf you serve MCP
3002A2AIf you serve A2A

Nodes behind NAT work without port forwarding; see Networking.

Run as a service

Run the node under a supervisor with automatic restart, so a crash or reboot brings it back with the same identity. On a TPM machine the keys are re-derived at boot with no console interaction.

ini
[Unit]
Description=Tenzro node
After=network-online.target
Wants=network-online.target

[Service]
User=tenzro
Environment=TENZRO_DATA_DIR=/var/lib/tenzro
ExecStart=/usr/local/bin/tenzro-node --roles validator
ExecStop=/usr/local/bin/tenzro-node graceful-exit
Restart=always

[Install]
WantedBy=multi-user.target

tenzro-node graceful-exit asks the running node to step down at a safe point before it stops. Never wipe the data directory to reset a node: it holds the node's chain state and configuration.

Containers

The repository ships Dockerfiles for each accelerator: Dockerfile (CPU), Dockerfile.cuda (x86-64 and ARM64), Dockerfile.rocm, Dockerfile.vulkan, and Dockerfile.trainer, which adds the training worker. The image runs as a non-root user with tenzro-node as its entrypoint and /data/tenzro as its data directory.

bash
docker build -f Dockerfile.cuda -t tenzro-node:cuda .

docker run -d --name tenzro --restart unless-stopped \
  --device /dev/tpmrm0 \
  -p 9000:9000/tcp -p 9000:9000/udp \
  -p 8545:8545 -p 8080:8080 \
  -v tenzro-data:/data/tenzro \
  tenzro-node:cuda \
  --data-dir /data/tenzro --roles ai \
  --rpc-addr 0.0.0.0:8545 --web-addr 0.0.0.0:8080

Pass the host's TPM device into the container so the node can root its identity. Keep the data volume across upgrades. The image's health check calls /verify/health on port 8080.

Orchestrators

Reference Kubernetes manifests live in deploy/kubernetes/ in the repository: a StatefulSet for validators, a Deployment for RPC nodes, services, a network policy and a pod disruption budget. Adapt them to your cluster.

  • Validators need stable peer addresses: use a Service per replica or host networking for port 9000, and set --external-p2p-addr to the address peers should dial.
  • Give each validator pod access to its node's TPM, and keep one validator per machine.
  • Use tenzro-node graceful-exit as the preStop hook.
  • Point liveness at /health and readiness at /ready. Neither is ever gated by a service key, so probes work on a private node.

Light and micro nodes

Laptops, desktops and edge devices can run a light node that follows the chain, verifies finality and relays without storing the full history:

bash
tenzro-node --roles light --data-dir ~/.tenzro

A micro node (--roles micro) is the smallest footprint, for devices that act mostly as a user of the network. Both work behind NAT. New full nodes can start from a snapshot instead of replaying the chain; see State and snapshots.

Monitoring

  • GET /health, GET /ready and GET /status on the Web API report liveness, readiness (height, lag behind the network tip, peer count) and node state.
  • GET /metrics serves Prometheus metrics.
  • Logs go to stdout; --log-format json produces structured logs and --log-level sets verbosity.
  • tenzro status shows live resource and traffic status from the command line.

Hardening checklist

  • Expose only the ports your roles need, and keep 8080/metrics and the admin token off the public internet.
  • Keep the admin token in your secret store and pass it through TENZRO_ADMIN_TOKEN; rotate it if it leaks.
  • Put a private node behind a service key. See RPC access.
  • Publish a signed operator policy that says what you serve and how; you are only slashed for provable breaches of your own policy. See Operator policies.
  • Subscribe to release announcements and upgrade promptly; run the same version as the network.