2025年如何优雅地部署ETH节点

近期因为业务扩展,尝试了自行部署ETH节点用于数据查询和区块链交互。过程中发现对于ETH节点的部署有很多更新,官方文档和网络信息都不太全面,问了ChatGPT也有发现很多不一样的地方。所以记录一下迄今为止踩过的坑。

首先众所周知的是,以太坊的节点对数据的存储需求特别巨大,所有的文档都要求至少2T的SSD磁盘才能满足基本需求。恰好手头买来的是一个双1T磁盘的独立服务器,默认配置直接启动还没有完成同步就已经把单个磁盘打满,自动退出,部署失败。

后来发现可以调整历史数据的规模和历史数据的存储路径,从而将单个节点的数据分散到两个磁盘上。 再接着又发现最新版本的节点已经不需要配置历史数据的长度了,历史数据的存储会在撑满磁盘之后自动被清理。

此外,绝大部分文档都要求在节点运行两周之后执行prune操作以压缩历史数据,把磁盘占用恢复到原始的650GB附近。实测发现最新版的节点已经默认启用的是新的文件管理方式(–state.scheme=path),不再需要停机进行数据压缩。节点在运行过程中会自行维护磁盘空间。

官方文档也说了: https://geth.ethereum.org/docs/fundamentals/pruning ,不需要在path模式使用pruning,但是官方文档却没有说明已经默认是path模式,还写着hash模式: --state.scheme value (default: "hash")

另外一点是在以太坊的merge升级之后,节点分为共识层和网络层,因此一个完整的节点需要同时启动两个程序分别处理各层的数据。参考了官方文档的介绍,我们使用geth+prysm的方式部署。涉及到两个程序之间的通讯有多种方式,既可以是http也可以是ipc文件,我们采用了本地rpc文件因为是在同一个机器上。

一个可用的docker compose配置文件如下:

version: '2'

services:
  defi_geth:
    image: ethereum/client-go:stable
    container_name: defi_geth
    volumes:
      - /root/data/geth:/root/.ethereum #这里指向geth的数据目录
      - /root/data/sdb/geth.ancient:/root/.ethereum.ancient #这里配置历史数据的存储,我们指向了sdb即第二个磁盘
      - ./buff:/root/buff #rpc文件的通讯目录
    ports:
      - 127.0.0.1:8545:8545
      - "30303:30303"
    command:
      - --http
      - --http.addr=0.0.0.0
      - --http.port=8545
      - --http.api=eth,web3,net,personal,engine,admin
      - --http.corsdomain=*
      - --http.vhosts=*
      - --ipcpath=/root/buff/geth.ipc
      - --datadir=/root/.ethereum
      - --datadir.ancient=/root/.ethereum.ancient
      - --cache=4096
      - --history.state=30000
      - --history.transactions=783333 #这行没用

  defi_prysm_beacon:
    image: gcr.io/prysmaticlabs/prysm/beacon-chain:stable
    container_name: defi_prysm_beacon
    restart: always
    volumes:
      - /root/.eth2:/data
      - ./buff:/root/buff
    ports:
      - "4000:4000" # P2P 网络端口
      - "13000:13000" # P2P 用户端口
      - "127.0.0.1:3500:3500" # GRPC 服务端口
      - "127.0.0.1:38080:8080" # Prysm API 服务端口
    command:
      - --datadir=/data
      - --execution-endpoint=/root/buff/geth.ipc # 指向 Geth 的 auth RPC 端点
    depends_on:
      - defi_geth

在启动之后可以通过如下的命令查询节点的运行状态:

curl -X POST http://127.0.0.1:8545   -H "Content-Type: application/json"   -d '{"jsonrpc":"2.0","method":"eth_syncing","params":[],"id":1}' | jq

样例输出在各种tutorial都有这里不再复制粘贴,一定要等到节点同步完成了才可以正常使用。