Seed Node Deployment
This guide covers deploying a seed node for any Monolythium network (Sprintnet, Testnet, or Mainnet). Seed nodes help new nodes discover peers and are essential network infrastructure.
Prerequisites
- Hardware: 4+ vCPU, 8GB+ RAM, 500GB+ SSD
- OS: Ubuntu 22.04 LTS or Debian 12
- Network: Static public IP, open firewall for P2P port
- Software: Docker (recommended) or Go 1.24+
Network Selection
Choose your target network. All configuration is fetched from the canonical registry:
| Network | Chain ID | Status | Registry URL |
|---|---|---|---|
| Sprintnet | mono-sprint-1 | Active | peers.json |
| Testnet | mono-test-1 | Planned | peers.json |
| Mainnet | mono-1 | Planned | peers.json |
Quick Start (Docker)
# Set your network (sprintnet, testnet, or mainnet)
NETWORK=sprintnet
# Fetch network configuration
REGISTRY_URL="https://raw.githubusercontent.com/monolythium/mono-core-peers/prod/networks/${NETWORK}/peers.json"
GENESIS_URL=$(curl -s $REGISTRY_URL | jq -r '.genesis_url')
GENESIS_SHA=$(curl -s $REGISTRY_URL | jq -r '.genesis_sha256')
CHAIN_ID=$(curl -s $REGISTRY_URL | jq -r '.chain_id')
PERSISTENT_PEERS=$(curl -s $REGISTRY_URL | jq -r '.persistent_peers | join(",")')
echo "Network: $NETWORK"
echo "Chain ID: $CHAIN_ID"
echo "Genesis SHA256: $GENESIS_SHA"
# Create data directory
sudo mkdir -p /opt/monod/config /opt/monod/data
cd /opt/monod
# Download and verify genesis
curl -sL $GENESIS_URL -o config/genesis.json
echo "$GENESIS_SHA config/genesis.json" | sha256sum -c -
# Run seed node container
docker run -d \
--name ${NETWORK}-seed \
--restart unless-stopped \
-v /opt/monod:/root/.monod \
-p 26656:26656 \
-p 26657:26657 \
ghcr.io/monolythium/monod:latest \
monod start \
--p2p.seed_mode=true \
--p2p.persistent_peers="$PERSISTENT_PEERS"
Full Setup (Systemd)
1. Install Binary
# Download latest release
VERSION=$(curl -s https://api.github.com/repos/monolythium/mono-core/releases/latest | jq -r '.tag_name')
curl -sL "https://github.com/monolythium/mono-core/releases/download/${VERSION}/monod-linux-amd64" -o /usr/local/bin/monod
chmod +x /usr/local/bin/monod
monod version
2. Fetch Network Configuration
# Set your network
NETWORK=sprintnet
# Fetch all configuration from registry
REGISTRY_URL="https://raw.githubusercontent.com/monolythium/mono-core-peers/prod/networks/${NETWORK}/peers.json"
GENESIS_URL=$(curl -s $REGISTRY_URL | jq -r '.genesis_url')
GENESIS_SHA=$(curl -s $REGISTRY_URL | jq -r '.genesis_sha256')
CHAIN_ID=$(curl -s $REGISTRY_URL | jq -r '.chain_id')
SEEDS=$(curl -s $REGISTRY_URL | jq -r '.seeds | join(",")')
PERSISTENT_PEERS=$(curl -s $REGISTRY_URL | jq -r '.persistent_peers | join(",")')
P2P_PORT=$(curl -s $REGISTRY_URL | jq -r '.port_scheme.seeds.p2p')
RPC_PORT=$(curl -s $REGISTRY_URL | jq -r '.port_scheme.seeds.rpc')
# Display configuration
echo "=== Network Configuration ==="
echo "Network: $NETWORK"
echo "Chain ID: $CHAIN_ID"
echo "P2P Port: $P2P_PORT"
echo "RPC Port: $RPC_PORT"
echo "Persistent Peers: $PERSISTENT_PEERS"
3. Initialize Node
# Create monod user
sudo useradd -r -s /sbin/nologin -m -d /var/lib/monod monod
# Initialize node
sudo -u monod monod init "seed-$(hostname)" --chain-id $CHAIN_ID --home /var/lib/monod
# Download genesis
sudo curl -sL $GENESIS_URL -o /var/lib/monod/config/genesis.json
sudo chown monod:monod /var/lib/monod/config/genesis.json
# Verify genesis SHA256
echo "$GENESIS_SHA /var/lib/monod/config/genesis.json" | sha256sum -c -
4. Configure Seed Mode
Edit /var/lib/monod/config/config.toml:
[p2p]
# Enable seed mode - node will crawl network and respond to peer requests
seed_mode = true
# Listen address for P2P connections
laddr = "tcp://0.0.0.0:26656"
# Advertise your public IP
external_address = "YOUR_PUBLIC_IP:26656"
# Persistent peers to connect to (validators or other seeds)
# Get this from the network registry
persistent_peers = "nodeid@host:port,..."
# Increase peer limits for seed nodes
max_num_inbound_peers = 100
max_num_outbound_peers = 50
Apply peers from registry:
# Use monoctl (recommended) or manual sed
monoctl config apply \
--home /var/lib/monod \
--persistent-peers "$PERSISTENT_PEERS"
# Or manually (be careful with sed!):
# Only replace exact key matches to avoid corrupting other config values
sudo -u monod sed -i "s|^persistent_peers = .*|persistent_peers = \"$PERSISTENT_PEERS\"|" /var/lib/monod/config/config.toml
sudo -u monod sed -i "s|^seed_mode = .*|seed_mode = true|" /var/lib/monod/config/config.toml
5. Create Systemd Service
cat <<EOF | sudo tee /etc/systemd/system/${NETWORK}-seed.service
[Unit]
Description=Monolythium Seed Node (${NETWORK})
After=network-online.target
Wants=network-online.target
[Service]
User=monod
Group=monod
Type=simple
ExecStart=/usr/local/bin/monod start --home /var/lib/monod
Restart=always
RestartSec=3
LimitNOFILE=65535
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable ${NETWORK}-seed
6. Configure Firewall
# Required: P2P port (default 26656)
sudo ufw allow 26656/tcp comment "Monolythium P2P"
# Optional: RPC port (only if you need remote access)
# sudo ufw allow 26657/tcp comment "Monolythium RPC"
sudo ufw reload
Network-specific ports:
Check the registry for custom port schemes:
curl -s $REGISTRY_URL | jq '.port_scheme'
Some networks (like Sprintnet) use non-standard ports for multi-validator setups. If connecting to validators on custom ports, ensure those ports are allowed.
7. Start and Verify
# Start the service
sudo systemctl start ${NETWORK}-seed
# Check status
sudo systemctl status ${NETWORK}-seed
# View logs
sudo journalctl -u ${NETWORK}-seed -f
# Verify sync status
curl -s localhost:26657/status | jq '.result.sync_info'
# Check peer count
curl -s localhost:26657/net_info | jq '.result.n_peers'
Seed Mode Configuration
Seeds have specific configuration requirements:
| Setting | Value | Description |
|---|---|---|
seed_mode | true | Enable seed mode behavior |
max_num_inbound_peers | 100+ | Accept many incoming connections |
max_num_outbound_peers | 50+ | Actively discover peers |
addr_book_strict | true | Only allow routable addresses |
pex | true | Enable peer exchange |
Pruning Policy
Seeds don't need full block history. Use aggressive pruning:
In app.toml:
[pruning]
pruning = "custom"
pruning-keep-recent = "100"
pruning-keep-every = "0"
pruning-interval = "10"
This keeps only the last 100 blocks, significantly reducing disk usage.
Common Issues
No Peers Found
-
Verify firewall allows P2P port:
sudo ufw status | grep 26656 -
Check persistent_peers format:
grep persistent_peers /var/lib/monod/config/config.toml
# Should be: nodeid@host:port -
Verify validators are reachable:
# From the registry
PEERS=$(curl -s $REGISTRY_URL | jq -r '.persistent_peers[]')
for peer in $PEERS; do
HOST=$(echo $peer | cut -d@ -f2 | cut -d: -f1)
PORT=$(echo $peer | cut -d: -f2)
echo "Testing $HOST:$PORT"
nc -zv $HOST $PORT 2>&1
done
Config Corruption
If config.toml was corrupted by manual editing, regenerate it:
sudo systemctl stop ${NETWORK}-seed
sudo -u monod monod init "seed-$(hostname)" --chain-id $CHAIN_ID --home /var/lib/monod --overwrite
# Re-apply genesis and config
AppHash Mismatch
If the seed reports an AppHash mismatch, reset state:
sudo systemctl stop ${NETWORK}-seed
sudo -u monod monod tendermint unsafe-reset-all --home /var/lib/monod --keep-addr-book
sudo systemctl start ${NETWORK}-seed
Register Your Seed
Once your seed is stable and synced, submit it to the network registry:
-
Get your node ID:
monod tendermint show-node-id --home /var/lib/monod -
Submit a PR to mono-core-peers adding your seed to
networks/<network>/peers.json:{
"seeds": [
"your_node_id@your_ip:26656"
]
}
See Also
- Seeds and Peers - Understanding peer types
- Deployment Modes - Docker vs Host-Native
- Monitoring - Setting up observability