→ updated on 01/20/23 for post-merge compatability & fixes
This is a quick & dirty guide to running Besu (execution client) & Lighthouse (consensus client) with Ubuntu and Docker primarily for testnet usage. It is aimed to be minimalistic and has client diversity in mind.
As a powerful sandboxing tool Docker offers high flexibility at minimized resource consumption and allows for potentially switching to different clients with ease (see bonus section of this guide).
Besu’s (by ConsenSys) latest additions of a refreshingly slim database structure (“Bonsai”) and checkpoint-sync functionality heave it back in contention with good ‘ol Geth as an execution client of choice. Lighthouse (by Sigma Prime) serves as lightweight, highly-reliable (beacon chain) consensus client, making it a great fit for a combined post-merge node setup.
Quick reminder: post-merge validators need to run both an execution AND consensus client to to be able to publish attestations and block proposals.
This guide assumes a pre-installed and hardened Ubuntu installation as well as Docker. Excellent introductory resources to start with are: eth-docker, coincashew and rocketpool
In order to have good peering for your clients you moreover want to open ports 30303 (Besu) and 9000 (Lighthouse) to the internet (TCP & UDP).
A potentially mainnet-proof hardware setup could look like:
Quad Core CPU (e.g. on a dedicated local Mini-PC like a Intel NUC10 or Asus PN50)
16 GB RAM
1-2 TB SSD (ideally NVMe, 2TB recommended for Besu mainnet database growth peace-of-mind)
If you intend to deploy on a VPS, please bear in mind extra adaptions for security.
Navigate in a terminal/CLI to your user’s /home
directory.
Create a project directory with subfolders and retrieve the Besu Docker image
$ mkdir -p ETHclient/{besu,lighthouse,teku,JWT}; cd ETHclient
$ docker pull hyperledger/besu:latest
Depending on your Docker configuration every Docker command should be preceded by sudo
Check the image
$ docker run hyperledger/besu:latest besu --version
Generate a JasonWebToken (JWT) so that the execution and consensus client can communicate securely
$ openssl rand -hex 32 | tr -d "\n" > "$(pwd)/JWT/jwtsecret"
Create a Docker network (to which your Docker containers will connect to)
$ docker network create ETHclient_net
Start/Run Besu (creates a container)
note: it will take some time to sync to the Ethereum Goerli testnet which is needed so that the consensus client functions properly.
$ docker run -d -it --rm --name besu --network ETHclient_net -p 30303:30303/tcp -p 30303:30303/udp -p 127.0.0.1:8545:8545 -p 127.0.0.1:8551:8551 -e JAVA_OPTS=-Xmx8g -v $HOME/ETHclient/besu:/opt/besu/data -v $HOME/ETHclient/JWT:/JWT hyperledger/besu:latest --network=goerli --data-path=/opt/besu/data/data --data-storage-format=BONSAI --sync-mode=X_CHECKPOINT --rpc-http-enabled --rpc-http-host=0.0.0.0 --rpc-http-api=ETH,NET,WEB3 --rpc-http-cors-origins=* --host-allowlist=* --engine-host-allowlist=* --engine-jwt-secret=/JWT/jwtsecret --engine-rpc-port=8551
Retrieve the Lighthouse Docker image
$ docker pull sigp/lighthouse:latest-modern
Check the image
$ docker run sigp/lighthouse:latest-modern lighthouse --version
Start/Run Lighthouse
note: it is recommended to use the lightning fast checkpoint sync
feature, representing a secure way to sync the PoS chain. Verify the initial state against a curated list of endpoint providers.
$ docker run -d -it --rm --name lh_beacon --network ETHclient_net -p 9000:9000/tcp -p 9000:9000/udp -p 127.0.0.1:5052:5052 -v $HOME/ETHclient/lighthouse:/root/.lighthouse -v $HOME/ETHclient/JWT:/JWT sigp/lighthouse:latest-modern lighthouse beacon --network=goerli --execution-endpoints=http://besu:8551 --execution-jwt=/JWT/jwtsecret --http --http-address 0.0.0.0 --checkpoint-sync-url=https://goerli.checkpoint-sync.ethdevops.io
Easily log/monitor containers with
$ docker logs -f besu # (exit with Ctrl+c)
$ docker logs -f lh_beacon
Stop container(s)
$ docker stop besu
$ docker stop lh_beacon
Update Besu / Lighthouse
Stop each container respectively before
$ docker pull hyperledger/besu:latest
$ docker pull sigp/lighthouse:latest-modern
Other potentially helpful Docker commands
$ docker ps # list containers
$ docker container prune # prune dangling containers
$ docker inspect network ETHclient_net # check Docker network
remove the second appearance of the --network
flag in the above described run commands, respectively (i.e. specifying the application, not the docker network)
Follow instructions and add “RPC URL” 127.0.0.1:8545
to circumvent centralized node infrastructure and instead use your own local node for chain interactions.
Welcome to the true rails of web3! 🥳
Stop Lighthouse → retrieve Teku Docker image → check the image → start/run Teku:
$ docker stop lh_beacon
$ docker pull consensys/teku:latest
$ docker run consensys/teku:latest teku --version
$ docker run -d -it --rm --name teku --network ETHclient_net -p 9000:9000/tcp -p 9000:9000/udp -p 127.0.0.1:5051:5051 -e JAVA_OPTS=-Xmx4g -v $HOME/ETHclient/teku:/var/lib/teku -v $HOME/ETHclient/JWT:/JWT consensys/teku:latest --data-base-path=/var/lib/teku --network=goerli --p2p-port=9000 --ee-endpoint=http://besu:8551 --ee-jwt-secret-file=/JWT/jwtsecret --rest-api-enabled=true --rest-api-docs-enabled=true
This guide assumes you’ve worked your way through
and have created your keystore-files. Subsequently, watch here how to deposit to the Prater testnet deposit contract. Afterwards:
Copy your validator keys into your mounted docker volume - following along the above described way, you will have to copy the “validator_keys” directory into $HOME/lh-besu/lighthouse
$ docker run -it --rm -v $HOME/ETHclient/lighthouse:/root/.lighthouse sigp/lighthouse:latest-modern lighthouse account validator import --directory=/root/.lighthouse/validator_keys
note: as the validator account manager account validator import
is running from inside Docker, a directory inside the container storage has to be referenced - as opposed to a local drive.
Start/Run Lighthouse validator
Make sure to NEVER run two instances of the same validating keys at once to avoid getting slashed and consequently lose your (testnet)ETH
$ docker run -d -it --rm --name lh_validator --network ETHclient_net -v $HOME/ETHclient/lighthouse:/root/.lighthouse sigp/lighthouse:latest-modern lighthouse vc --network=goerli --beacon-nodes="http://lh_beacon:5052"
Monitor your validator
and identify your validating public key(s) starting with “0x”
$ docker logs -f lh_validator
alternatively you can check $HOME/ETHclient/lighthouse/prater/validators/validator_definitions.yml
Also, monitor the status of your validator(s) by entering your validating public key(s) on
$ docker exec -it lh_validator lighthouse account validator exit --beacon-node http://lh_beacon:5052 --keystore /root/.lighthouse/prater/validators/<0x_yourvalidatorkey>/voting-keystore.json
EthStaker (shout-out to Yorick for invaluable feedback!), ConsenSys, and Lighthouse Discord servers are very welcoming places for further questions and advice.
****
Please keep in mind this is a testnet guide that may contain mistakes and that takes shortcuts which come with trade-offs. It could quickly become outdated as it’s subject to ever evolving network and client changes.
****
featured image CC BY-NC 2.0 by Barry Stock
****
This post was retroactively supported by a grant from a CLR funding round held by EthStaker, mainly matched by the EF.