The Agent is one of the two execution backends. It’s a single standalone binary written in TypeScript and compiled to a self-contained executable withDocumentation Index
Fetch the complete documentation index at: https://docs.novacula.io/llms.txt
Use this file to discover all available pages before exploring further.
bun build --compile. It runs as a systemd service and manages every blockchain node process on the host as its own systemd service too.
For the Operator (Kubernetes) backend, see Operator (Kubernetes).
When to use
- One Linux host, or a small fleet of hosts you already manage with Ansible / Terraform / cloud-init.
- You don’t want a Kubernetes dependency for blockchain nodes.
- The node workload sits on dedicated hardware (typical for bare-metal colo).
Requirements
- OS — Ubuntu 22.04+ or Debian 12+ (other glibc-based Linux distros likely work but aren’t tested).
- Architecture —
x86_64oraarch64. - Privileges —
rootorsudo(the agent writes to/etc/systemd/systemand reads/proc). - Network — outbound HTTPS to the control plane URL. No inbound ports needed.
- Storage — a single
data_dir(default/var/lib/novacula) that holds the agent’s state, downloaded client binaries, per-node config, and per-node data directories. Size it for the largest chain you plan to run (e.g. Tron mainnet wants ~4 TB).
Three concurrent loops
The agent runs three independent loops on a single Bun process:| Loop | Default cadence | Job |
|---|---|---|
| PollingClient | 5s | Long-poll the control plane for the latest spec for every assigned node. |
| Reconciler | 5s | Diff desired vs observed. Generate config, install missing client binaries, write systemd units, start/stop services. |
| Reporter | 10s | Probe each node process’s metrics endpoint, build an ObservedNodeState, write it back via syncExecutor. |
How it materializes a node
For each node the control plane assigns:- Resolve the chain adapter for the spec’s
chain. - Generate config files — the adapter writes one or more files into
<data_dir>/nodes/<name>/config/. - Install client binaries — if the chosen client+version isn’t already in
<data_dir>/bin/, download it. Install URLs come from the adapter; integrity is checked when the upstream provides hashes. - Create init steps — for chains with init needs (Sui genesis blob, Ethereum JWT secret, Tron snapshot, …), run the adapter’s
initContainerSpecs()once. - Write a systemd unit per process —
<chain>-<role>@<node>.servicestyle.ExecStart=calls the client binary directly with the adapter-managed flags + user overrides. systemctl daemon-reload && systemctl start <unit>. The reconciler exits; on the next tick it’ll seeobservedStatus = starting, thenrunning, thensyncing.
The agent’s own systemd unit
The agent installs itself asnovacula-agent.service plus a one-shot rollback unit:
Restart=on-failure,StartLimitBurst=3overStartLimitIntervalSec=120.OnFailure=novacula-agent-rollback.service— invoked if the agent flap-budget is exhausted. The rollback unitmvs the previous binary (kept as<current>.prevafter every self-update) back over the broken one and restarts.
Self-update
When the control plane sets apendingUpgrade on this executor’s row, the agent:
- Downloads the new binary into a sibling temp file.
- Verifies SHA-256.
- Verifies a minisign signature against trusted public keys baked into the running binary (not configurable at runtime).
- Hardlinks the current binary as
<current>.prevfor the rollback unit. - Atomic
rename()over the current binary. systemctl restart novacula-agent.service.
pendingUpgrade once it sees the match.
CLI
The agent ships with a Citty-based CLI for install, lifecycle, status, and manual upgrade. See Agent CLI for the full subcommand list.See also
- Provision an executor on bare-metal — install walkthrough.
- Configuration reference — agent TOML schema.
- Environment variables — env vars the agent reads.
- Connect an executor — generate the API key the agent will use.