🐳Docker
Authors: [ Ankur | Dapplooker]
System Requirements
CPU
OS
RAM
DISK
8 vCPU
Ubuntu 22.04
16 GB
2 TB
The Berachain node has a size of 1.6 TiB on 10, June, 2025.
Pre-requisite
Before starting, clean the setup then update and upgrade. Install following:
Docker
curl
jq
Commands
sudo apt update -y && sudo apt upgrade -y && sudo apt auto-remove -y
sudo apt install docker.io ufw -y jq -y
Firewall Settings
Check status & enable UFW
sudo ufw enable
sudo ufw status verbose
Set explicit default UFW rules
sudo ufw default deny incoming
sudo ufw default allow outgoing
Allow SSH, HTTP, and HTTPS
sudo ufw allow 22/tcp
sudo ufw allow 80
sudo ufw allow 443
Allow Remote connection
sudo ufw allow from ${REMOTE.HOST.IP} to any port 25445
Setup Instructions
1
Setup Project Directory
mkdir berachain ;
cd berachain ;
Create setup-node.sh file.
#!/bin/bash
set -e
echo "Berachain Mainnet Archive Node Setup"
# Check prerequisites
if ! command -v docker >/dev/null 2>&1; then
echo "ERROR: Docker is not installed"
exit 1
fi
if ! command -v curl >/dev/null 2>&1; then
echo "ERROR: curl is not installed"
exit 1
fi
# Create directory structure
echo "Creating directories..."
rm -rf data config
mkdir -p data/geth data/beacond/config config
# Download configuration files
echo "Downloading configuration files..."
GENESIS_URL="https://raw.githubusercontent.com/berachain/beacon-kit/refs/heads/main/testing/networks/80094/genesis.json"
ETH_GENESIS_URL="https://raw.githubusercontent.com/berachain/beacon-kit/refs/heads/main/testing/networks/80094/eth-genesis.json"
KZG_TRUSTED_URL="https://raw.githubusercontent.com/berachain/beacon-kit/refs/heads/main/testing/networks/80094/kzg-trusted-setup.json"
CONFIG_TOML_URL="https://raw.githubusercontent.com/berachain/beacon-kit/refs/heads/main/testing/networks/80094/config.toml"
APP_TOML_URL="https://raw.githubusercontent.com/berachain/beacon-kit/refs/heads/main/testing/networks/80094/app.toml"
EL_PEERS_URL="https://raw.githubusercontent.com/berachain/beacon-kit/refs/heads/main/testing/networks/80094/el-peers.txt"
curl -s -o config/consensus-genesis.json "$GENESIS_URL" || { echo "ERROR: Failed to download consensus genesis"; exit 1; }
curl -s -o config/eth-genesis.json "$ETH_GENESIS_URL" || { echo "ERROR: Failed to download execution genesis"; exit 1; }
curl -s -o data/beacond/kzg-trusted-setup.json "$KZG_TRUSTED_URL" || { echo "ERROR: Failed to download KZG trusted setup"; exit 1; }
curl -s -o config/config.toml "$CONFIG_TOML_URL" || { echo "ERROR: Failed to download config.toml"; exit 1; }
curl -s -o config/app.toml "$APP_TOML_URL" || { echo "ERROR: Failed to download app.toml"; exit 1; }
curl -s -o config/el-peers.txt "$EL_PEERS_URL" || { echo "ERROR: Failed to download EL peers"; exit 1; }
# Generate JWT secret
echo "Generating JWT secret..."
if command -v openssl >/dev/null 2>&1; then
openssl rand -hex 32 | tr -d '\n' | sed -e 's/^/0x/' > data/jwtsecret
elif command -v head >/dev/null 2>&1 && [ -f /dev/urandom ]; then
head -c 32 /dev/urandom | xxd -p -c 32 | tr -d '\n' | sed -e 's/^/0x/' > data/jwtsecret
else
echo "ERROR: Cannot generate JWT secret. Install openssl."
exit 1
fi
# Get public IP
PUBLIC_IP=$(curl -s https://ipv4.icanhazip.com/ 2>/dev/null || curl -s https://api.ipify.org 2>/dev/null || echo "127.0.0.1")
# Configure Beacond
echo "Configuring Beacond..."
cp config/config.toml data/beacond/config/config.toml
cp config/app.toml data/beacond/config/app.toml
# Update config.toml with better P2P settings
sed -i 's/moniker = ".*"/moniker = "berachain-archive-node"/' data/beacond/config/config.toml
sed -i 's#laddr = "tcp://.*:26656"#laddr = "tcp://0.0.0.0:25456"#' data/beacond/config/config.toml
sed -i "s#external_address = \".*\"#external_address = \"$PUBLIC_IP:25456\"#" data/beacond/config/config.toml
sed -i 's#laddr = "tcp://.*:26657"#laddr = "tcp://0.0.0.0:26657"#' data/beacond/config/config.toml
# P2P connectivity settings
sed -i 's/max_num_inbound_peers = .*/max_num_inbound_peers = 40/' data/beacond/config/config.toml
sed -i 's/max_num_outbound_peers = .*/max_num_outbound_peers = 10/' data/beacond/config/config.toml
sed -i 's/dial_timeout = ".*"/dial_timeout = "10s"/' data/beacond/config/config.toml
sed -i 's/handshake_timeout = ".*"/handshake_timeout = "20s"/' data/beacond/config/config.toml
sed -i 's/pex = .*/pex = true/' data/beacond/config/config.toml
sed -i 's/seed_mode = .*/seed_mode = false/' data/beacond/config/config.toml
sed -i 's/allow_duplicate_ip = .*/allow_duplicate_ip = true/' data/beacond/config/config.toml
# Set better seed configuration - use official mainnet seeds
cat >> data/beacond/config/config.toml << 'EOF'
# Mainnet seeds for better connectivity
seeds = "[email protected]:26656,[email protected]:26656,[email protected]:26656"
persistent_peers = ""
EOF
# Update app.toml
sed -i 's/pruning = ".*"/pruning = "nothing"/' data/beacond/config/app.toml
sed -i 's#rpc-dial-url = ".*"#rpc-dial-url = "http://bera-geth:8551"#' data/beacond/config/app.toml
sed -i 's#jwt-secret-path = ".*"#jwt-secret-path = "/jwtsecret"#' data/beacond/config/app.toml
sed -i 's#trusted-setup-path = ".*"#trusted-setup-path = "/beacond/kzg-trusted-setup.json"#' data/beacond/config/app.toml
sed -i 's/enabled = false/enabled = true/g' data/beacond/config/app.toml
sed -i 's#address = ".*:3500"#address = "0.0.0.0:3500"#' data/beacond/config/app.toml
cp config/consensus-genesis.json data/beacond/config/genesis.json
# Clean any existing Geth data to prevent state scheme conflicts
echo "Cleaning Geth data directory..."
rm -rf data/geth/*
# Initialize Geth
echo "Initializing Geth..."
docker run --rm \
-v "$(pwd)/data/geth:/data" \
-v "$(pwd)/config:/config" \
ethereum/client-go:v1.15.10 \
init --datadir=/data --db.engine=pebble --state.scheme=hash /config/eth-genesis.json
# Initialize Beacond
echo "Initializing Beacond..."
docker run --rm \
-v "$(pwd)/data/beacond:/beacond" \
ghcr.io/berachain/beacon-kit:v1.2.0 \
init berachain --chain-id=mainnet-beacon-80094 --home=/beacond --overwrite
# Restore configurations
cp config/consensus-genesis.json data/beacond/config/genesis.json
cp config/config.toml data/beacond/config/config.toml
cp config/app.toml data/beacond/config/app.toml
# Re-apply configurations
sed -i 's/moniker = ".*"/moniker = "berachain-archive-node"/' data/beacond/config/config.toml
sed -i 's#laddr = "tcp://.*:26656"#laddr = "tcp://0.0.0.0:25456"#' data/beacond/config/config.toml
sed -i "s#external_address = \".*\"#external_address = \"$PUBLIC_IP:25456\"#" data/beacond/config/config.toml
sed -i 's#laddr = "tcp://.*:26657"#laddr = "tcp://0.0.0.0:26657"#' data/beacond/config/config.toml
# Re-apply P2P settings
sed -i 's/max_num_inbound_peers = .*/max_num_inbound_peers = 40/' data/beacond/config/config.toml
sed -i 's/max_num_outbound_peers = .*/max_num_outbound_peers = 10/' data/beacond/config/config.toml
sed -i 's/dial_timeout = ".*"/dial_timeout = "10s"/' data/beacond/config/config.toml
sed -i 's/handshake_timeout = ".*"/handshake_timeout = "20s"/' data/beacond/config/config.toml
sed -i 's/pex = .*/pex = true/' data/beacond/config/config.toml
sed -i 's/seed_mode = .*/seed_mode = false/' data/beacond/config/config.toml
sed -i 's/allow_duplicate_ip = .*/allow_duplicate_ip = true/' data/beacond/config/config.toml
# Add seeds again
cat >> data/beacond/config/config.toml << 'EOF'
# Mainnet seeds for better connectivity
seeds = "[email protected]:26656,[email protected]:26656,[email protected]:26656"
persistent_peers = ""
EOF
sed -i 's/pruning = ".*"/pruning = "nothing"/' data/beacond/config/app.toml
sed -i 's#rpc-dial-url = ".*"#rpc-dial-url = "http://bera-geth:8551"#' data/beacond/config/app.toml
sed -i 's#jwt-secret-path = ".*"#jwt-secret-path = "/jwtsecret"#' data/beacond/config/app.toml
sed -i 's#trusted-setup-path = ".*"#trusted-setup-path = "/beacond/kzg-trusted-setup.json"#' data/beacond/config/app.toml
sed -i 's/enabled = false/enabled = true/g' data/beacond/config/app.toml
sed -i 's#address = ".*:3500"#address = "0.0.0.0:3500"#' data/beacond/config/app.toml
# Prepare bootnode string
EL_PEERS=$(cat config/el-peers.txt | tr '\n' ',' | sed 's/,$//')
echo "$EL_PEERS" > config/bootnode-string.txt
# Create environment file
cat > .env << EOF
PUBLIC_IP=$PUBLIC_IP
EL_BOOTNODES=$EL_PEERS
GETH_VERSION=v1.15.10
BEACOND_VERSION=v1.2.0
EOF
echo "Setup completed successfully"
echo "Start node: docker compose up -d"
make the scrip executable :
chmod +x setup-node.sh ;
2
Create Docker Compose File
Create docker-compose.yml file.
services:
# Geth Execution Layer
bera-geth:
image: ethereum/client-go:${GETH_VERSION:-v1.15.10}
container_name: bera-geth
restart: unless-stopped
stop_grace_period: 10m
networks:
- berachain
ports:
- "25403:25403/tcp" # P2P networking
- "25403:25403/udp"
- "25445:8545" # JSON-RPC
- "25446:8546" # WebSocket
volumes:
- ./data/geth:/data
- ./data/jwtsecret:/jwtsecret:ro
- ./config/bootnode-string.txt:/bootnode-string.txt:ro
- /etc/localtime:/etc/localtime:ro
environment:
- GETH_DATADIR=/data
entrypoint: ["/bin/sh", "-c"]
command:
- |
BOOTNODES=$$(cat /bootnode-string.txt) &&
exec geth \
--datadir=/data \
--db.engine=pebble \
--state.scheme=hash \
--port=25403 \
--discovery.port=25403 \
--nat=extip:${PUBLIC_IP:-127.0.0.1} \
--gcmode=archive \
--syncmode=full \
--networkid=80094 \
--bootnodes="$$BOOTNODES" \
--maxpeers=100 \
--netrestrict="" \
--cache=8192 \
--http \
--http.addr=0.0.0.0 \
--http.port=8545 \
--http.corsdomain=* \
--http.api=eth,net,web3,txpool,debug,trace,admin,engine \
--ws \
--ws.addr=0.0.0.0 \
--ws.port=8546 \
--ws.origins=* \
--ws.api=eth,net,web3,txpool,debug,trace,admin,engine \
--authrpc.addr=0.0.0.0 \
--authrpc.port=8551 \
--authrpc.vhosts=* \
--authrpc.jwtsecret=/jwtsecret
# Beacond Consensus Layer
bera-beacond:
image: ghcr.io/berachain/beacon-kit:${BEACOND_VERSION:-v1.2.0}
container_name: bera-beacond
restart: unless-stopped
stop_grace_period: 10m
networks:
- berachain
ports:
# P2P networking
- "25456:25456/tcp"
- "25456:25456/udp"
- "25457:26657" # RPC
- "25430:3500" # Beacon API
volumes:
- ./data/beacond:/beacond
- ./data/jwtsecret:/jwtsecret:ro
- /etc/localtime:/etc/localtime:ro
environment:
- BEACOND_HOME=/beacond
command:
- start
- --home=/beacond
networks:
berachain:
driver: bridge
3
Execute Node Configuration
./setup-node.sh
#Berachain Mainnet Archive Node Setup
#Creating directories...
#Downloading configuration files...
#Generating JWT secret...
#Configuring Beacond...
#Cleaning Geth data directory...
#Initializing Geth...
...
...
...
#Setup completed successfully
#Start node: docker compose up -d
Monitoring
Monitor Logs of Docker Container
docker ps
docker logs bera-geth
docker logs bera-beacond
Total time required to sync is ~4 days
Sync Status
Latest Block
curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' http://localhost:25445
Response should look like:
{"jsonrpc":"2.0","id":1,"result":"0x5e7ac2"}
REFERENCES
Last updated