Running a Node
Complete operational guide for running Orbinum nodes in development, testnet, and production modes.
Make sure you've completed the Installation before continuing.
Node Modes Overview
| Mode | Use Case | Data Persistence | Consensus | Pre-funded Accounts |
|---|---|---|---|---|
| Development | Local testing | Temporal (with --tmp) | Instant seal | Alice, Bob, Charlie |
| Testnet | Integration testing | Persistent | Multi-validator | No (requires faucet) |
| Production | Mainnet | Persistent | Multi-validator | No |
Development Mode
Mode for local development with instant seal (produces blocks without consensus). Everything runs from the published Docker image — no compilation.
The examples use ghcr.io/orbinum/node:testnet-latest. Export it once to keep
commands short: export ORB=ghcr.io/orbinum/node:testnet-latest.
Basic Development Node
docker run --rm ghcr.io/orbinum/node:testnet-latest --dev --tmp
Flags:
--dev: Activates development chain spec with pre-funded accounts--tmp: Stores data in temporary directory (cleared on restart)
Features:
- Produces blocks instantly (doesn't wait for consensus)
- Clean chain state on each start
- Ideal for quick testing
Pre-funded Development Accounts
| Account | Substrate Address | Initial Balance |
|---|---|---|
| Alice | 5GrwvaEF... | 1,000,000 ORB |
| Bob | 5FHneW46... | 1,000,000 ORB |
| Charlie | 5FLSigC9... | 1,000,000 ORB |
With Persistent Data
To keep state between restarts, mount a host directory (or a named volume):
docker run --rm -v "$PWD/data:/data" ghcr.io/orbinum/node:testnet-latest \
--dev --base-path /data
Enable External RPC Access
To connect from Polkadot.js Apps or external wallets, publish the RPC port:
docker run --rm -p 9944:9944 ghcr.io/orbinum/node:testnet-latest \
--dev --tmp \
--rpc-cors all \
--rpc-methods Unsafe \
--rpc-external
--rpc-methods Unsafe enables dangerous methods, and -p 9944:9944 exposes the
RPC port. Local development only — never on a public node.
With Ethereum RPC APIs
For EVM development (MetaMask, Hardhat, etc.):
docker run --rm -p 9944:9944 ghcr.io/orbinum/node:testnet-latest \
--dev --tmp \
--rpc-cors all \
--rpc-external \
--ethapi=debug,trace,txpool
Available endpoints:
- Substrate RPC:
ws://127.0.0.1:9944 - Ethereum RPC:
http://127.0.0.1:9944(JSON-RPC compatible)
Testnet Mode
Docker Deployment (Recommended)
The testnet runs from a pre-built image on GitHub Container Registry — you do not compile from source. There are two roles, each with its own compose file:
| Role | Compose file | Purpose |
|---|---|---|
| Validator | docker-compose.yml | Produces blocks, participates in consensus |
| RPC / bootnode | docker-compose.rpc.yml | Public HTTPS/WSS endpoint for dApps & wallets; entry point for other nodes |
git clone https://github.com/orbinum/node.git
cd node/docker/testnet
# Authenticate with GHCR (the node image is private)
echo <GITHUB_TOKEN> | docker login ghcr.io -u <github_user> --password-stdin
cp .env.example .env # validator (or .env.rpc.example for an RPC)
nano .env # fill in the values for your node
docker compose pull # pull the published image (no build step)
docker compose up -d
docker compose logs -f orbinum-validator
Container management:
docker compose logs -f orbinum-validator # live logs
docker compose ps # status
docker compose restart orbinum-validator # restart (needed after key insertion)
docker compose down # stop
Validator firewall & P2P
A validator must not expose its RPC port. Open only what it needs:
sudo ufw allow 30333/tcp # P2P — must be publicly reachable for public validators
sudo ufw allow 22/tcp # SSH
sudo ufw enable
The RPC port stays inside the container and is reached via docker compose exec
during key insertion only. Exposing it lets anyone drive your node.
After the node syncs, insert session keys and complete the registration flow (bond, session keys, EVM relay, approval). See Validator Registration.
Public RPC Node (Testnet)
An RPC node serves the public HTTPS/WSS endpoint and acts as a bootnode. It
does not participate in consensus. Use docker-compose.rpc.yml, which bundles
the node plus a Caddy reverse proxy (TLS) behind Cloudflare.
cd node/docker/testnet
cp .env.rpc.example .env
nano .env # set RPC_NAME, RPC_NODE_KEY, RPC_DOMAIN
docker compose -f docker-compose.rpc.yml pull
docker compose -f docker-compose.rpc.yml build caddy # custom Caddy + rate-limit plugin
docker compose -f docker-compose.rpc.yml up -d
Hardening (DDoS protection). A public RPC is an attack surface — these layers matter:
-
Cloudflare proxy — set the
rpc-*DNS records to Proxied and SSL/TLS mode to Full (Strict). Cloudflare absorbs L3/L4 + L7 attacks and enforces a rate limit (100 req / 10s per IP). Add a WAF Skip rule for managed bot challenges on the RPC host, or non-browser clients (indexers, wallets) get blocked. -
Origin certificate — Caddy terminates TLS with a Cloudflare Origin Certificate (
*.testnet.orbinum.io), mounted asorigin.pem/origin.key. -
Origin firewall — allow
80/443only from Cloudflare's IP ranges, so a leaked origin IP can't be hit directly. Deny9944and9615entirely.sudo ufw allow 22/tcp
sudo ufw allow 30333/tcp # P2P / bootnode
for ip in $(curl -s https://www.cloudflare.com/ips-v4); do
sudo ufw allow from "$ip" to any port 443 proto tcp
sudo ufw allow from "$ip" to any port 80 proto tcp
done
sudo ufw deny 9944 && sudo ufw deny 9615
sudo ufw enable -
Resource limits — the node service is capped (
RPC_MEM_LIMIT,RPC_CPUSin.env; defaults6g/3CPU) so a query flood can't starve the host.
For the complete walkthrough (Cloudflare Advanced Certificate, origin cert creation, Caddy rate-limit config), see the RPC / Bootnode setup guide in the node repo.
Local Multi-Node Testnet
To simulate a small network locally with the well-known --alice / --bob
keys, run two containers on a shared Docker network:
docker network create orbinum-local
Node 1 (Alice — bootnode):
docker run --rm --name alice --network orbinum-local \
-p 9944:9944 ghcr.io/orbinum/node:testnet-latest \
--chain local --alice --tmp \
--port 30333 --rpc-port 9944
Copy the Local node identity from Alice's logs (format 12D3KooW...).
Node 2 (Bob):
docker run --rm --name bob --network orbinum-local \
-p 9945:9944 ghcr.io/orbinum/node:testnet-latest \
--chain local --bob --tmp \
--port 30333 --rpc-port 9944 \
--bootnodes /dns/alice/tcp/30333/p2p/<ALICE_PEER_ID>
Replace <ALICE_PEER_ID> with the identity from Alice's logs. Both nodes
discover each other over the orbinum-local network and finalize blocks
together.
Orbinum is in the testnet phase (Q1 2026: MVP / Testnet). Production / mainnet deployment is not yet available — this guide covers development and testnet only.
Configuration Reference
Essential Flags
| Flag | Description | Default |
|---|---|---|
--chain | Chain specification | dev |
--base-path | Data directory | Platform-specific |
--port | P2P port | 30333 |
--rpc-port | RPC port | 9944 |
--ws-port | WebSocket port | 9944 |
--validator | Enable validation | false |
--pruning | State pruning mode | 256 blocks |
--name | Node name | Random |
RPC Configuration
| Flag | Description |
|---|---|
--rpc-external | Listen on all interfaces |
--rpc-cors | CORS origins (use all for dev) |
--rpc-methods | Safe, Unsafe, or Auto |
--rpc-max-connections | Max concurrent connections |
Logging
# Increase verbosity
docker run --rm -e RUST_LOG=debug $ORB --dev --tmp
# Specific module logging
docker run --rm -e RUST_LOG=pallet_shielded_pool=trace $ORB --dev --tmp
# Log to file
docker run --rm $ORB --dev --tmp 2>&1 | tee node.log
$ORBis the image shorthand from Development Mode (export ORB=ghcr.io/orbinum/node:testnet-latest).
Monitoring and Observability
Prometheus Metrics
Enable metrics endpoint:
docker run --rm -p 9615:9615 $ORB \
--dev --tmp \
--prometheus-port 9615 \
--prometheus-external
Access: http://localhost:9615/metrics
Available metrics:
- Block height, finalization lag
- Transaction pool size
- Peer connections
- Memory usage, CPU
RPC Health Check
curl -H "Content-Type: application/json" \
-d '{"id":1, "jsonrpc":"2.0", "method": "system_health", "params":[]}' \
http://localhost:9944
Response:
{
"jsonrpc": "2.0",
"result": {
"peers": 5,
"isSyncing": false,
"shouldHavePeers": true
},
"id": 1
}
Advanced Topics
Custom Chain Spec
To create a custom chain spec:
# Generate spec in JSON format
docker run --rm $ORB build-spec --chain local > custom-spec.json
# Convert to raw format
docker run --rm -v "$PWD:/specs" $ORB \
build-spec --chain /specs/custom-spec.json --raw > custom-spec-raw.json
# Use the spec
docker run --rm -v "$PWD:/specs" $ORB --chain /specs/custom-spec-raw.json
Database Backend
Orbinum uses RocksDB by default. To change:
# Use ParityDB (experimental)
docker run --rm $ORB --dev --tmp --database paritydb
Telemetry
Send telemetry to public server:
docker run --rm $ORB \
--chain testnet \
--name "MyNode" \
--telemetry-url "wss://telemetry.polkadot.io/submit/ 0"
Next Steps
- Quick Start - Perform your first transaction
- Validator Registration - Register as a testnet validator