Skip to main content

Running a Node

Complete operational guide for running Orbinum nodes in development, testnet, and production modes.

Prerequisites

Make sure you've completed the Installation before continuing.


Node Modes Overview


ModeUse CaseData PersistenceConsensusPre-funded Accounts
DevelopmentLocal testingTemporal (with --tmp)Instant sealAlice, Bob, Charlie
TestnetIntegration testingPersistentMulti-validatorNo (requires faucet)
ProductionMainnetPersistentMulti-validatorNo

Development Mode

Mode for local development with instant seal (produces blocks without consensus). Everything runs from the published Docker image — no compilation.

Image shorthand

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

AccountSubstrate AddressInitial Balance
Alice5GrwvaEF...1,000,000 ORB
Bob5FHneW46...1,000,000 ORB
Charlie5FLSigC9...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
Development Only

--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

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:

RoleCompose filePurpose
Validatordocker-compose.ymlProduces blocks, participates in consensus
RPC / bootnodedocker-compose.rpc.ymlPublic 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
Never expose port 9944 on a validator

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.

Key insertion and registration

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:

  1. 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.

  2. Origin certificate — Caddy terminates TLS with a Cloudflare Origin Certificate (*.testnet.orbinum.io), mounted as origin.pem / origin.key.

  3. Origin firewall — allow 80/443 only from Cloudflare's IP ranges, so a leaked origin IP can't be hit directly. Deny 9944 and 9615 entirely.

    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
  4. Resource limits — the node service is capped (RPC_MEM_LIMIT, RPC_CPUS in .env; defaults 6g / 3 CPU) so a query flood can't starve the host.

Full RPC guide

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.


Mainnet not live yet

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

FlagDescriptionDefault
--chainChain specificationdev
--base-pathData directoryPlatform-specific
--portP2P port30333
--rpc-portRPC port9944
--ws-portWebSocket port9944
--validatorEnable validationfalse
--pruningState pruning mode256 blocks
--nameNode nameRandom

RPC Configuration

FlagDescription
--rpc-externalListen on all interfaces
--rpc-corsCORS origins (use all for dev)
--rpc-methodsSafe, Unsafe, or Auto
--rpc-max-connectionsMax 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

$ORB is 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