We're using QuickNode for Base Sepolia. This post is how to setup our own node.
1. Prerequisites
- Docker & Docker Compose installed.
- L1 RPC Endpoint: A synced Ethereum Sepolia node (e.g., Geth + Lighthouse).
- L1 Beacon Endpoint: Required for post-Canyon/Ecotone consensus.
- Hardware: Minimum 16GB RAM and 1.5TB+ NVMe SSD.
2. The Automated Setup Script
We use a wrapper script to handle directory creation, JWT generation, and repository patching. This ensures your local paths are correctly mapped into the Docker containers.
Save as setup-base-sepolia.sh:
#!/usr/bin/env bash
set -e
echo "🚀 Initializing Base Sepolia Setup..."
BASE_DIR="/node-data/testnet/base-sepolia"
REPO_DIR="/opt/base-node"
# 1. Create directory layout
echo "📁 Creating data directories..."
mkdir -p ${BASE_DIR}/{op-geth,op-node,shared}
# 2. Generate the JWT Secret (The "Handshake" Key)
if [ ! -f "${BASE_DIR}/shared/jwt.txt" ]; then
echo "🔑 Generating 32-byte hex JWT..."
# CRITICAL: No 0x prefix, no newlines.
openssl rand -hex 32 | tr -d "\n" > ${BASE_DIR}/shared/jwt.txt
chmod 644 ${BASE_DIR}/shared/jwt.txt
fi
# 3. Clone the official Base Node Repo
echo "📦 Cloning base-org/node..."
if [ ! -d "${REPO_DIR}" ]; then
git clone https://github.com/base-org/node.git ${REPO_DIR}
fi
cd ${REPO_DIR}
# 4. Create .env.sepolia
echo "⚙️ Writing environment configuration..."
cat > .env.sepolia <<EOF
# L1 Endpoints (Replace with your actual L1 IPs)
OP_NODE_L1_ETH_RPC=http://testnet:8585
OP_NODE_L1_BEACON=http://testnet-lighthouse:5052
# L2 Execution & Auth
OP_NODE_L2_ENGINE_RPC=http://execution:8551
OP_NODE_L2_ENGINE_AUTH=jwt
OP_NODE_L2_ENGINE_JWT_SECRET=/shared/jwt.txt
# Network & Sync
OP_NODE_NETWORK=base-sepolia
OP_NODE_SYNC_MODE=snap
EOF
# 5. Patch docker-compose.yml for custom volumes
echo "🛠 Patching docker-compose volumes..."
# Map op-geth and op-node to host paths
sed -i 's|${HOST_DATA_DIR}:/data|/node-data/testnet/base-sepolia/op-geth:/data|g' docker-compose.yml
# Inject the shared JWT volume into both services
sed -i '/volumes:/a \ - /node-data/testnet/base-sepolia/shared:/shared' docker-compose.yml
# 6. Start the stack
echo "🚀 Starting containers..."
docker compose --env-file .env.sepolia up -d
3. Critical Configuration Check
For the node to function, your entrypoint scripts inside the repo must use the correct environment variables.
-
execution-entrypoint: Ensure--authrpc.jwtsecret="$OP_NODE_L2_ENGINE_JWT_SECRET"is set. -
op-node-entrypoint: Ensure--l2.jwt-secret="$OP_NODE_L2_ENGINE_JWT_SECRET"is set. -
Networking: Ensure
--rpc.addr=0.0.0.0is set in both to allow external monitoring.
4. Troubleshooting & Mastery 🔍
If your node isn't syncing, check these three layers in order:
Layer 1: The JWT Handshake
If op-node cannot talk to op-geth, you will see 401 Unauthorized.
-
Check:
docker exec execution-1 cat /shared/jwt.txt - Fix: Ensure the file is exactly 64 characters long. If it contains "true" or a file path instead of hex, your script logic is overwriting the secret.
Layer 2: L1 Connectivity
The op-node derives L2 blocks from L1 data. If L1 is down, L2 stops.
-
Check:
docker exec node-1 curl -s http://testnet:8585 - Fix: Ensure your L1 node is fully synced and reachable on the Docker network.
Layer 3: P2P Peering
In snap sync mode, you need peers to download the state.
-
Check:
curl -s -d '{"id":1,"jsonrpc":"2.0","method":"opp2p_peerStats"}' http://localhost:9645 | jq -
Fix: Ensure ports
30303(Geth) and9222(Node) are open on your firewall.
5. Monitoring Your Progress
The most important command for a node operator is the Sync Status. It tells you exactly where you are in history.
The "Scoreboard" Command:
watch -n 5 'curl -s -X POST -H "Content-Type: application/json" --data "{\"jsonrpc\":\"2.0\",\"method\":\"optimism_syncStatus\",\"params\":[],\"id\":1}" http://localhost:9645 | jq ".result.local_safe_l2.number, .result.local_safe_l2.timestamp"'
- First Number: Current L2 Block Height.
- Second Number: Unix Timestamp of that block (compare this to the current time to see how many days/months you are behind).
Summary
- Generate a clean JWT.
- Align your volumes so both containers see the same
/shared/jwt.txt. - Point to a healthy L1 RPC and Beacon node.
- Monitor via
optimism_syncStatus.
Top comments (0)