Run a node — deploy guide

Hardware picks, three install paths, every env var explained, monitoring, troubleshooting. Fifteen minutes end-to-end on a fresh VPS.

Hardware

OptionCostExpected tierCaveats
Raspberry Pi 5 (8 GB)~$80 one-timeT1Residential bandwidth fine. Keep it on a UPS.
Home NAS / mini-PC0 if you own oneT1–T2Dual-boot friendly. Watch for NAT issues (port-forward 8545).
$5 VPS (Hetzner, Vultr, DO)$5/moT1–T2Best uptime-for-price ratio. Default pick for most operators.
Dedicated / bare-metal$50–$200/moT3–T4Pair with paid Alchemy/Infura keys. Target 99.5%+ uptime bonus.

Install — three paths

Path 1: One-liner (Ubuntu 22.04+ / Debian 12+)

curl -fsSL https://metercall.ai/install-node.sh | sudo bash

Runs as root. Installs Node 20, clones the repo to /opt/metercall-node, creates a metercall system user, writes a systemd unit, and prompts for your stake address + region.

Path 2: Docker

docker run -d \
  --name metercall-node \
  --restart unless-stopped \
  -p 8545:8545 \
  -e STAKE_ADDRESS=0xYourAddress \
  -e NODE_KEY=$(openssl rand -hex 32) \
  -e REGION=us-east \
  -e UPSTREAM_RPCS='{"ethereum":"https://rpc.ankr.com/eth","polygon":"https://rpc.ankr.com/polygon"}' \
  metercall/node:0.1.0

Or use the docker-compose.yml in /node/ — just fill out a .env file and docker compose up -d.

Path 3: Manual (any platform)

git clone https://github.com/patl4588/metercall-site.git
cd metercall-site/node
export STAKE_ADDRESS=0xYourAddress
export NODE_KEY=$(openssl rand -hex 32)
export REGION=us-east
node index.js

Node 18+ required. No npm install needed — the runtime has zero dependencies.

Configuration — every env var

VariableDefaultPurpose
NODE_KEYrandom32-byte hex HMAC secret for receipt signing. Treat as private. 0.2.0 upgrades to secp256k1.
STAKE_ADDRESS(required)Ethereum address holding your staked PCP. Rewards credited here.
COORDINATOR_URLhttps://metercall.aiCoordinator base URL. Only change for testnet.
UPSTREAM_RPCS{}JSON map chain_id → rpc_url. See config-home.js and config-pro.js.
PORT8545HTTP listen port.
REGIONunknownRegion label. Used for geo-routing and the map on /nodes.html.
NODE_NAMEmetercall-nodeFriendly handle shown in the public registry.
HEARTBEAT_MS60000Heartbeat interval (ms). Minimum 10000.
EPOCH_MS86400000Epoch length (24h). Don't change unless running a local testnet.

Monitoring

Troubleshooting — 8 common issues

  1. Node shows offline in registry. Check curl https://metercall.ai/api/node/heartbeat is reachable; your firewall may block outbound. Open port 443 outbound.
  2. Calls return upstream_error. Your public RPC is rate-limiting. Switch to paid (Alchemy/Infura) or rotate multiple public RPCs per chain.
  3. Receipts not counted for rewards. Verify STAKE_ADDRESS is set and matches the address that staked in NodeStaking.sol. Receipts from unstaked addresses are dropped silently.
  4. Systemd fails to start: status=200/CHDIR. The installer sets WorkingDirectory=/opt/metercall-node/node. Verify the repo was cloned correctly.
  5. Port 8545 already in use. You likely have a local Ethereum node. Set PORT=8546 in /etc/metercall/node.env and restart.
  6. Slashed unexpectedly. Read the on-chain SlashExecuted event — it includes a reason string. 99% of cases are a rate-limited upstream returning bogus data, not operator malice.
  7. Docker healthcheck failing but node works. The Alpine image uses wget; if busybox wget is missing --spider, rebuild against node:20-alpine fresh. Known fixed in 0.1.0.
  8. Heartbeat spam in logs. Set HEARTBEAT_MS=120000 to halve it. Don't go above 5 minutes or you'll get flagged as offline.

Upgrade policy