Bootstrap Operations
Run a Talero bootnode
A bootnode exists to help the network find peers quickly and reliably.
It should be stable, reachable on P2P, and conservative about everything else.
This guide describes a public-safe bootnode pattern using the Talero container deployment path.
Bootnode
P2P first
Private RPC
No public metrics
A bootnode is not the place to expose public RPC, explorer traffic, or admin tooling.
Keep the node narrow and predictable.
Requirements
- A Linux host with a stable public IP or DNS name for the P2P address.
- Public network reachability for the Talero P2P port.
- Docker Engine and Docker Compose plugin.
- The Talero node repository or release bundle on the host.
- Canonical mainnet identity material:
TALERO_EXPECTED_CHAIN_ID,
TALERO_EXPECTED_GENESIS_HASH,
TALERO_GENESIS_TIMESTAMP_SECS,
and the approved bootnode strategy for your deployment.
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
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
Bootnode role model
In the current codebase, TALERO_ROLE=bootnode is accepted as a bootnode deployment shape,
while the runtime still uses the fullnode-class role internally for most general behavior.
The bootnode distinction matters in startup safety checks and P2P treatment.
- Set
TALERO_ROLE=bootnode.
- Set
TALERO_IS_BOOTNODE=1.
- Keep
TALERO_DISABLE_MINING=1.
- Keep RPC private and read-only.
A designated bootnode may start with an empty TALERO_BOOTNODES list.
A normal non-bootnode mainnet node cannot do that by default.
Create the bootnode environment file
cd /opt/talero/node
cat > .env.mainnet.bootnode <<'EOF'
TALERO_NETWORK=mainnet
TALERO_ROLE=bootnode
TALERO_IS_BOOTNODE=1
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; host exposure stays loopback-only
TALERO_RPC_LISTEN=0.0.0.0:8547
TALERO_RPC_READONLY=1
TALERO_RPC_PUBLIC_MODE=0
# P2P
TALERO_P2P_LISTEN=0.0.0.0:30303
TALERO_P2P_SELF_ADDR=YOUR_PUBLIC_IP:30303
TALERO_BOOTNODES=
# Bootnode posture
TALERO_DISABLE_MINING=1
TALERO_EVM_ENABLED=1
TALERO_EVM_REPLAY_ON_STARTUP=1
TALERO_EVM_REPLAY_STRICT_STARTUP=1
TALERO_SAFE_MODE_ENABLED=1
TALERO_SAFE_MODE_MANUAL_OVERRIDE=auto
# Logging
TALERO_LOG=info
TALERO_LOG_FORMAT=json
EOF
If this node is not one of the root bootnodes, replace the empty TALERO_BOOTNODES with the approved bootstrap list.
Do not copy a public IP address from another environment into this file.
Port model
A bootnode needs public P2P ports and private RPC. Use a compose override that publishes RPC only to host loopback.
cd /opt/talero/node
cat > docker-compose.mainnet.bootnode-private-rpc.yml <<'EOF'
services:
talero-node:
ports:
- "127.0.0.1:8547:8547"
- "30303:30303"
- "30303:30303/udp"
EOF
| Surface |
Recommended exposure |
Why |
| P2P TCP and UDP |
Public |
Peers need to discover and dial the bootnode. |
| RPC |
Host loopback only |
Bootnodes should not be public RPC servers. |
| /metrics |
Private only |
Keep operational telemetry off the public internet. |
Start the bootnode
cd /opt/talero/node
TALERO_ENV_FILE=.env.mainnet.bootnode \
docker compose \
-f docker-compose.mainnet.yml \
-f docker-compose.mainnet.bootnode-private-rpc.yml \
up -d
cd /opt/talero/node
TALERO_ENV_FILE=.env.mainnet.bootnode \
docker compose \
-f docker-compose.mainnet.yml \
-f docker-compose.mainnet.bootnode-private-rpc.yml \
logs -f talero-node
Verify node health
curl -sS http://127.0.0.1:8547/health | jq '{
ok,
network,
role,
head,
sync,
p2p
}'
curl -sS -X POST http://127.0.0.1:8547/rpc \
-H 'content-type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"talero_getNetworkInfo","params":{}}'
- The node should come up with peer connectivity and stable P2P listening.
p2p.peersTotal should increase once peers begin dialing or once the node starts dialing known peers.
- RPC should remain private and read-only from a network-exposure perspective.
Upgrade flow
cd /opt/talero/node
tar -C ./data -czf bootnode-backup-$(date -u +%Y%m%d-%H%M%S).tgz .
docker compose -f docker-compose.mainnet.yml build
TALERO_ENV_FILE=.env.mainnet.bootnode \
docker compose \
-f docker-compose.mainnet.yml \
-f docker-compose.mainnet.bootnode-private-rpc.yml \
up -d
Troubleshooting
| Error shape |
Likely cause |
Fix |
requires TALERO_EXPECTED_GENESIS_HASH |
Fresh mainnet datadir without identity guard values. |
Set expected chain ID, genesis hash, and timestamp. |
bootnodes invalid |
The configured bootnode list is malformed. |
Use valid IP:PORT entries separated by commas, or leave it empty only for a designated root bootnode. |
| No peers arrive |
P2P port is blocked or self address is wrong. |
Check firewall, cloud security group, and TALERO_P2P_SELF_ADDR. |
cd /opt/talero/node
TALERO_ENV_FILE=.env.mainnet.bootnode \
docker compose \
-f docker-compose.mainnet.yml \
-f docker-compose.mainnet.bootnode-private-rpc.yml \
logs --tail=200 talero-node