Talero Fullnode Guide
Detailed, public-safe install and operations guide
Fullnode Operations

Run a Talero fullnode

A Talero fullnode is the standard builder and integration node: it syncs the network, serves JSON-RPC and REST, participates in transaction gossip, and can power private or hardened public infrastructure. This guide follows the repository's containerized path and stays inside the public-safe boundary.

Fullnode Mainnet-oriented Public RPC possible Privacy hardened

This page does not publish admin CIDRs, trusted proxy ranges, signer secrets, or other deployment-specific controls. Keep those details in your private operations material.

Requirements

  • A persistent Linux host with storage for /data.
  • Docker Engine and Docker Compose plugin.
  • The Talero node repository or release bundle on the host.
  • Canonical mainnet identity material from the approved release process: TALERO_EXPECTED_CHAIN_ID, TALERO_EXPECTED_GENESIS_HASH, TALERO_GENESIS_TIMESTAMP_SECS, and the current bootnode list.
  • A clear decision about whether the node will stay private or sit behind a hardened public RPC edge.

Install Docker on Ubuntu

If the host is fresh, use Docker's official Ubuntu flow. For updates or distro-specific changes, verify against the official Docker Engine install guide for Ubuntu.

sudo apt-get update
sudo apt-get install -y ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo \"${UBUNTU_CODENAME:-$VERSION_CODENAME}\") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo usermod -aG docker "$USER"

Log out and back in after changing Docker group membership.

Prepare the deployment files

sudo mkdir -p /opt/talero
sudo chown "$USER":"$USER" /opt/talero
cd /opt/talero

# Place the Talero node release or repository here
# Required files include:
#   Dockerfile
#   docker-compose.mainnet.yml
#   docs/
#   tools/
cd /opt/talero/node
docker compose -f docker-compose.mainnet.yml build

The canonical release profile in the repository expects the default feature set, including hybrid PoW / PoS-BFT, REVM, checkpoint-notary, safe-mode, honeytrap, and network-health.

Mainnet chain identity

On a fresh mainnet datadir, the node refuses to initialize unless the expected genesis hash and matching genesis timestamp are present. It also checks the expected chain ID against the actual runtime identity.

  • Set TALERO_EXPECTED_CHAIN_ID to the approved mainnet chain ID.
  • Set TALERO_EXPECTED_GENESIS_HASH to the canonical mainnet genesis hash.
  • Set TALERO_GENESIS_TIMESTAMP_SECS to the exact genesis timestamp used by that chain.
  • Set TALERO_BOOTNODES to the current canonical bootnode list.

Do not add consensus-critical override variables such as TALERO_CHAIN_ID, TALERO_EVM_BLOCK_GAS_LIMIT, or PQ_REQUIRED_FROM_HEIGHT on a normal mainnet fullnode. The mainnet startup guard rejects that pattern by default.

Choose the RPC exposure model

For a containerized fullnode, the safe default is to let the node listen on container 0.0.0.0:8547, but publish that port to host loopback only. If you want public RPC, terminate it through a controlled reverse proxy.

Recommended host-loopback override

cd /opt/talero/node
cat > docker-compose.mainnet.private-rpc.yml <<'EOF'
services:
  talero-node:
    ports:
      - "127.0.0.1:8547:8547"
      - "30303:30303"
      - "30303:30303/udp"
EOF
Surface Recommended exposure Why
RPC Host loopback or reverse proxy Lets you harden the public edge without publishing raw node ports.
P2P TCP and UDP Public The fullnode needs normal peer connectivity.
/metrics Private only Operational telemetry should not be internet-facing by default.

Create the fullnode environment file

cd /opt/talero/node
cat > .env.mainnet.fullnode <<'EOF'
TALERO_NETWORK=mainnet
TALERO_ROLE=fullnode
TALERO_ROLE_STRICT=1

# Canonical chain identity from the approved mainnet release process
TALERO_EXPECTED_CHAIN_ID=REPLACE_WITH_CHAIN_ID
TALERO_EXPECTED_GENESIS_HASH=0xREPLACE_WITH_CANONICAL_GENESIS_HASH
TALERO_GENESIS_TIMESTAMP_SECS=REPLACE_WITH_CANONICAL_GENESIS_TIMESTAMP

# RPC inside the container
TALERO_RPC_LISTEN=0.0.0.0:8547
TALERO_RPC_PUBLIC_MODE=1
TALERO_RPC_READONLY=0
TALERO_RPC_TRUST_X_FORWARDED_FOR=0

# P2P
TALERO_P2P_LISTEN=0.0.0.0:30303
TALERO_P2P_SELF_ADDR=YOUR_PUBLIC_IP:30303
TALERO_BOOTNODES=BOOTNODE_A:30303,BOOTNODE_B:30303

# Fullnode behavior
TALERO_DISABLE_MINING=1
TALERO_EVM_ENABLED=1
TALERO_EVM_REPLAY_ON_STARTUP=1
TALERO_EVM_REPLAY_STRICT_STARTUP=1

# Public RPC hardening
TALERO_PRIVACY_ENABLED=1
TALERO_PRIVACY_PUBLIC_MODE=masked
TALERO_HONEYTRAP_ENABLED=1
TALERO_SAFE_MODE_ENABLED=1
TALERO_SAFE_MODE_MANUAL_OVERRIDE=auto

# Logging
TALERO_LOG=info
TALERO_LOG_FORMAT=json
EOF

This is a public-safe starting point. It deliberately leaves out admin CIDRs, trusted CIDRs, mining CIDRs, and proxy trust ranges because those are infrastructure-specific and should stay out of public docs.

If the node remains entirely private, you can set TALERO_RPC_PUBLIC_MODE=0. If it sits behind a public builder edge, keep public mode on and let privacy, honeytrap, and safe-mode do their work.

Start the fullnode

cd /opt/talero/node
TALERO_ENV_FILE=.env.mainnet.fullnode \
docker compose \
  -f docker-compose.mainnet.yml \
  -f docker-compose.mainnet.private-rpc.yml \
  up -d
cd /opt/talero/node
TALERO_ENV_FILE=.env.mainnet.fullnode \
docker compose \
  -f docker-compose.mainnet.yml \
  -f docker-compose.mainnet.private-rpc.yml \
  logs -f talero-node

Verify node health

curl -sS http://127.0.0.1:8547/health | jq '{
  ok,
  network,
  role,
  head,
  finalized,
  sync,
  p2p,
  rpc
}'
curl -sS -X POST http://127.0.0.1:8547/rpc \
  -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"eth_chainId","params":[]}'
curl -sS -X POST http://127.0.0.1:8547/rpc \
  -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","id":2,"method":"talero_getPrivacyConfig","params":{}}'
  • role should be "fullnode".
  • sync.hasSeenPeer should turn true after bootstrapping.
  • p2p.peersTotal should rise above zero.
  • If you intend to expose public RPC, confirm the privacy config and safe-mode status through RPC before you put traffic on the node.

Upgrade flow

cd /opt/talero/node
tar -C ./data -czf fullnode-backup-$(date -u +%Y%m%d-%H%M%S).tgz .

docker compose -f docker-compose.mainnet.yml build

TALERO_ENV_FILE=.env.mainnet.fullnode \
docker compose \
  -f docker-compose.mainnet.yml \
  -f docker-compose.mainnet.private-rpc.yml \
  up -d

After restart, repeat the health and RPC checks.

Troubleshooting

Error shape Likely cause Fix
requires TALERO_BOOTNODES Mainnet bootnode list is missing. Set the canonical mainnet bootnodes.
requires TALERO_EXPECTED_GENESIS_HASH Fresh mainnet datadir without identity guards. Set expected chain ID, genesis hash, and genesis timestamp.
chain_id() is still 1337 You are using a devnet-style build or incorrect release material. Deploy the approved mainnet build or release bundle.
Public RPC looks masked or redacted Privacy hardening is active. This is expected on public mode. Use a private integration node for unredacted access.
cd /opt/talero/node
TALERO_ENV_FILE=.env.mainnet.fullnode \
docker compose \
  -f docker-compose.mainnet.yml \
  -f docker-compose.mainnet.private-rpc.yml \
  logs --tail=200 talero-node