Running a Base Node
This tutorial walks you through setting up and running your own Base Node using Docker.
Objectives
By the end of this tutorial, you should be able to:
- Configure and deploy a Base node using Docker Compose.
- Select the network (Mainnet or Sepolia Testnet).
- Choose a client implementation (Geth, Reth, Nethermind).
- Start the synchronization process.
Prerequisites
Hardware Requirements
Refer to the Node Performance guide for detailed hardware recommendations. Minimums include:
- A modern multi-core CPU.
- 32 GB RAM (64 GB recommended).
- A locally attached NVMe SSD drive.
- Sufficient storage:
(2 * [current chain size](https://base.org/stats) + [snapshot size](https://basechaindata.vercel.app) + 20% buffer)
.
Docker
This section assumes you are familiar with Docker and have Docker and Docker Compose installed and running.
L1 Endpoints
You need access to synced Ethereum L1 (execution and consensus) endpoints. These can be self-hosted or from a third-party provider. You will need:
- L1 Execution RPC URL: An HTTP(S) endpoint for the L1 execution client.
- L1 Beacon API URL: An HTTP(S) endpoint for the L1 consensus client Beacon API.
- L1 Beacon Archiver API URL: An HTTP(S) endpoint for an L1 consensus client Beacon API with archival capabilities.
These URLs will be configured in your .env.mainnet
or .env.testnet
file later.
Setting Up and Running the Node
-
Clone the Repository: Clone the official Base Node repository:
git clone https://github.com/base/node.git cd node
-
Choose Network and Configure L1 Endpoints:
- Select the environment file for your desired network:
- Mainnet:
.env.mainnet
- Testnet:
.env.sepolia
- Mainnet:
- Open the chosen
.env
file (e.g.,.env.mainnet
) and configure your L1 endpoints:# .env.mainnet or .env.sepolia OP_NODE_L1_ETH_RPC=<your-L1-execution-rpc-url> OP_NODE_L1_BEACON=<your-L1-beacon-api-url> OP_NODE_L1_BEACON_ARCHIVER=<your-L1-beacon-archiver-api-url>
- Optional: Also set
OP_NODE_L1_RPC_KIND
based on your L1 provider (e.g.,alchemy
,quicknode
,infura
,debug_geth
,erigon
,basic
,any
). See the.env
file comments for supported values.
- Select the environment file for your desired network:
-
Start the Node with Docker Compose:
-
Use the following commands to build and start the node containers.
-
Mainnet (Default Client - Geth):
docker compose up --build -d
The
-d
flag runs the containers in detached mode (in the background). -
Sepolia Testnet (Default Client - Geth):
NETWORK_ENV=.env.sepolia docker compose up --build -d
-
Specifying a Client (e.g., Reth on Mainnet): Choose between
geth
(default),reth
, ornethermind
.CLIENT=reth docker compose up --build -d
-
Sepolia Testnet with a Specific Client (e.g., Reth):
NETWORK_ENV=.env.sepolia CLIENT=reth docker compose up --build -d
-
-
Verify Node is Running: Check if the node is responding to RPC requests. It might take a few minutes for the services to start.
curl -d '{"id":0,"jsonrpc":"2.0","method":"eth_chainId"}' \ -H "Content-Type: application/json" http://localhost:8545 # Expected Mainnet output: {"jsonrpc":"2.0","id":0,"result":"0x2105"} # Expected Sepolia output: {"jsonrpc":"2.0","id":0,"result":"0xaa36a7"}
Syncing your node can take hours to days, depending on hardware, network, and whether you use a snapshot. It consumes significant resources.
Snapshots
Using a snapshot significantly reduces the initial time required to sync a Base node. Snapshots are updated regularly.
If you're a prospective or current Base node operator, you can restore from a snapshot to speed up your initial sync. Follow the steps below carefully.
Restoring from Snapshot
These steps assume you are in the cloned node
directory (the one containing docker-compose.yml
).
-
Prepare Data Directory:
- Before running Docker for the first time, create the data directory on your host machine that will be mapped into the Docker container. This directory must match the
volumes
mapping in thedocker-compose.yml
file for the client you intend to use.- For Geth:
mkdir ./geth-data
- For Reth:
mkdir ./reth-data
- For Geth:
- If you have previously run the node and have an existing data directory, stop the node (
docker compose down
), remove the contents of the existing directory (e.g.,rm -rf ./geth-data/*
), and proceed.
- Before running Docker for the first time, create the data directory on your host machine that will be mapped into the Docker container. This directory must match the
-
Download Snapshot: Choose the appropriate snapshot for your network and client from the table below. Use
wget
or a similar tool to download it into thenode
directory.Network Client Snapshot Type Download Command ( wget ...
)Testnet Geth Full https://sepolia-full-snapshots.base.org/$(curl https://sepolia-full-snapshots.base.org/latest)
Testnet Reth Archive https://sepolia-reth-archive-snapshots.base.org/$(curl https://sepolia-reth-archive-snapshots.base.org/latest)
Mainnet Geth Full https://mainnet-full-snapshots.base.org/$(curl https://mainnet-full-snapshots.base.org/latest)
Mainnet Reth Archive https://mainnet-reth-archive-snapshots.base.org/$(curl https://mainnet-reth-archive-snapshots.base.org/latest)
-
Extract Snapshot: Untar the downloaded snapshot archive. Replace
<snapshot-filename.tar.gz>
with the actual downloaded filename.tar -xzvf <snapshot-filename.tar.gz>
-
Move Data: The extraction process will likely create a directory (e.g.,
geth
or similar, check the output of thetar
command).- Move the contents of this extracted directory into the data directory you created in Step 1.
- Example (if archive extracted to a
geth
folder):# For Geth mv ./geth/* ./geth-data/ rm -rf ./geth # Clean up empty extracted folder
- Example (if archive extracted to a
reth
folder - verify actual folder name):# For Reth mv ./reth/* ./reth-data/ rm -rf ./reth # Clean up empty extracted folder
- Example (if archive extracted to a
- The goal is to have the chain data (directories like
chaindata
,nodes
,segments
, etc.) directly inside./geth-data
or./reth-data
, not within an extra subfolder.
- Move the contents of this extracted directory into the data directory you created in Step 1.
-
Start the Node: Now that the snapshot data is in place, start the node using the appropriate command (see the Running a Base Node guide):
# Example for Mainnet Geth docker compose up --build -d
-
Verify and Clean Up: Monitor the node logs (
docker compose logs -f <service_name>
) or use the sync monitoring command to ensure the node starts syncing from the snapshot's block height. Once confirmed, you can safely delete the downloaded snapshot archive (.tar.gz
file) to free up disk space.
Monitoring Sync Progress
You can monitor the sync status using the optimism_syncStatus
RPC method:
echo Latest synced block behind by: $((($(date +%s)-$( \
curl -d '{"id":0,"jsonrpc":"2.0","method":"optimism_syncStatus"}' \
-H "Content-Type: application/json" http://localhost:7545 | \
jq -r .result.unsafe_l2.timestamp))/60)) minutes
If you attempt transactions or deployments before the node is fully synced, you might encounter errors like Error: nonce has already been used
.
Optional Features
The Base Node configuration supports optional features like EthStats monitoring and Trusted RPC mode. These can be enabled by uncommenting the relevant sections in your .env
file (.env.mainnet
or .env.sepolia
).
Advanced Configuration and Networking (Geth)
The standard Base Node Docker setup for Geth uses specific configurations and exposes several ports. Understanding these can be helpful for firewall rules, monitoring, and advanced tuning.
Default Network Ports (Geth Container)
- HTTP RPC:
8545
(Configurable via$RPC_PORT
in.env
) - WebSocket RPC:
8546
(Configurable via$WS_PORT
in.env
) - Authenticated RPC (Engine API):
8551
(Configurable via$AUTHRPC_PORT
in.env
) - Metrics:
6060
(Configurable via$METRICS_PORT
in.env
) - P2P Discovery/Connection:
30303
(Configurable via$P2P_PORT
in.env
)
Ensure these ports are accessible as needed, especially the P2P port (30303
) for peer discovery if your node is behind a firewall.
Improving Peer Connectivity
For better peer discovery, especially if running behind NAT, you can specify your external IP address. Add the following line to your .env.mainnet
or .env.sepolia
file:
# .env.mainnet or .env.sepolia
ADDITIONAL_ARGS="--nat=extip:<your-external-ip-address>"
Replace <your-external-ip-address>
with your actual public IP. You also need to ensure the P2P port (default 30303
) is open and forwarded correctly in your firewall/router configuration.
Geth Configuration via Environment Variables
Several Geth parameters can be tuned by setting environment variables in your .env.mainnet
or .env.sepolia
file:
- Verbosity:
GETH_VERBOSITY
(Default:3
) - Controls log level. - Sync Mode:
OP_GETH_SYNCMODE
(Default:full
) - Geth sync strategy. - GC Mode:
OP_GETH_GCMODE
(Default:full
) - Garbage collection mode. - Cache Settings:
GETH_CACHE
,GETH_CACHE_DATABASE
, etc. (See Node Performance). - Transaction Pool:
GETH_TXPOOL_GLOBALQUEUE
,GETH_TXPOOL_GLOBALSLOTS
,GETH_TXPOOL_LIFETIME
,TXPOOL_PRICE_LIMIT
. Fine-tuning these requires understanding Geth's transaction pool mechanics.
Refer to the official Geth documentation for details on these parameters.
Base/Rollup Specific Flags
The entrypoint script passes rollup-specific flags necessary for Base operation, such as:
--rollup.disabletxpoolgossip=true
: Disables standard L1 transaction gossip over P2P.--rollup.halt=major
: Halts the node on major configuration mismatches with the L1 chain.--op-network="$OP_NODE_NETWORK"
: Sets the specific OP Stack network configuration (e.g.,base-mainnet
).
Advanced Configuration and Networking (Reth)
The standard Base Node Docker setup for Reth also uses specific configurations.
Default Network Ports & Sockets (Reth Container)
- HTTP RPC:
8545
(Configurable via$RPC_PORT
in.env
) - WebSocket RPC:
8546
(Configurable via$WS_PORT
in.env
) - Authenticated RPC (Engine API):
8551
(Configurable via$AUTHRPC_PORT
in.env
) - Metrics:
6060
(Configurable via$METRICS_PORT
in.env
) - IPC Socket:
/data/reth.ipc
(Path configurable via--ipcpath
flag, see Reth docs) - P2P Discovery/Connection: Default
30303
(Configurable via--port
flag, see Reth docs)
Ensure these ports/sockets are accessible as needed.
Node Type and Flashblocks
The NODE_TYPE
environment variable (default: vanilla
) determines the Reth binary used:
vanilla
: Uses the standardop-reth
binary.base
: Uses thebase-reth-node
binary.
When NODE_TYPE
is set to base
, you can enable Flashblocks support by setting the RETH_FB_WEBSOCKET_URL
environment variable in your .env
file to your Flashblocks relay endpoint.
Reth Configuration via Environment Variables
Key Reth parameters are configured via environment variables in .env.mainnet
or .env.sepolia
:
- Chain Spec:
RETH_CHAIN
(Required, e.g.,base
,base_sepolia
) - Specifies the network configuration. - Sequencer Endpoint:
RETH_SEQUENCER_HTTP
(Required) - URL of the Base sequencer.
Other Reth CLI flags can often be passed via ADDITIONAL_ARGS
in the .env
file, but consult the official Reth documentation for available options and syntax.
Verbosity
The default Reth entrypoint runs with high verbosity (-vvv
). This can be adjusted by modifying the entrypoint script directly or potentially overriding the command in a custom docker-compose.override.yml
file.
Base/Rollup Specific Flags
The entrypoint script passes rollup-specific flags necessary for Base operation, such as:
--rollup.sequencer-http
: Configures the sequencer endpoint.--rollup.disable-tx-pool-gossip
: Disables standard L1 transaction gossip over P2P.