Skip to content

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

  1. Clone the Repository: Clone the official Base Node repository:

    git clone https://github.com/base/node.git
    cd node
  2. Choose Network and Configure L1 Endpoints:

    • Select the environment file for your desired network:
      • Mainnet: .env.mainnet
      • Testnet: .env.sepolia
    • 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.
  3. 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, or nethermind.

      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
  4. 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).

  1. 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 the docker-compose.yml file for the client you intend to use.
      • For Geth: mkdir ./geth-data
      • For Reth: mkdir ./reth-data
    • 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.
  2. 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 the node directory.

    NetworkClientSnapshot TypeDownload Command (wget ...)
    TestnetGethFullhttps://sepolia-full-snapshots.base.org/$(curl https://sepolia-full-snapshots.base.org/latest)
    TestnetRethArchivehttps://sepolia-reth-archive-snapshots.base.org/$(curl https://sepolia-reth-archive-snapshots.base.org/latest)
    MainnetGethFullhttps://mainnet-full-snapshots.base.org/$(curl https://mainnet-full-snapshots.base.org/latest)
    MainnetRethArchivehttps://mainnet-reth-archive-snapshots.base.org/$(curl https://mainnet-reth-archive-snapshots.base.org/latest)
  3. Extract Snapshot: Untar the downloaded snapshot archive. Replace <snapshot-filename.tar.gz> with the actual downloaded filename.

    tar -xzvf <snapshot-filename.tar.gz>
  4. Move Data: The extraction process will likely create a directory (e.g., geth or similar, check the output of the tar 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
    • 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.
  5. 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
  6. 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 standard op-reth binary.
  • base: Uses the base-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.