# How to Run an Ephemery Public Testnet Node with Besu and Teku In this tutorial, I’m going to walk you through how I set up an Ephemery testnet node using Besu for the execution layer and Teku for the consensus layer. If you're curious about running your own Ethereum-like beacon chain locally or just want a clean test environment that resets every four weeks, Ephemery is a great choice. I'll show you exactly what I did to get it up and running. Not to mention that went through the process as a normal user. So there is no need for special skills in DevOps, you can do it! >[!Note] This is a beacon node only (without validator duties)! - Prerequisites Docker & Docker-Compose installed ## Step 1: Set Up Your Working Directory Start by creating a project folder: ```bash mkdir ephemery-node && cd ephemery-node ``` ## Step 2: Download the Latest Ephemery Files fetch the file and unpack it inside testnet-all folder ```bash curl -L -o testnet-all.tar.gz https://github.com/ephemery-testnet/ephemery-genesis/releases/latest/download/testnet-all.tar.gz mkdir testnet-all && tar -xzf testnet-all.tar.gz -C testnet-all ``` ## Step 3: Load the environment variables ```bash cd testnet-all source nodevars_env.txt cd .. ``` This will give you access to: - `$BOOTNODE_ENODE` – for Besu - `$BOOTNODE_ENR_LIST` – for Teku You can run echo `$BOOTNODE_ENODE` to check the values if needed. You should now have: ```bash echo "$BOOTNODE_ENODE" # e.g. enode://…@IP:30303 echo "$BOOTNODE_ENR_LIST" # e.g. enr:-… ,enr:-… echo "$GENESIS_SSZ_PATH" # genesis.ssz echo "$CONFIG_YAML_PATH" # config.yaml ``` Create a .env file in the same directory as your docker-compose.yml and paste in the values from your nodevars_env.txt like this(values are real): ```env BOOTNODE_ENODE=enode://50a54ecbd2175497640bcf46a25bbe9bb4fae51d7cc2a29ef4947a7ee17496cf39a699b7fe6b703ed0feb9dbaae7e44fc3827fcb7435ca9ac6de4daa4d983b3d@137.74.203.240:30303 BOOTNODE_ENR_LIST=enr:-LK4QM7kEZAgPNZmwuEdfS68qxtvXmdY0Uk4mSrflr3gDTFTNAS09cRc-eLE-Gb-1Mc6FqOJgphhAEFDc52Kil2HWOsEh2F0dG5ldHOIAAAAAMAAAACEZXRoMpDOicPBYAAQG___________gmlkgnY0gmlwhIlKy_CJc2VjcDI1NmsxoQNOcwdwpHPZTopFyzuvy2XT2k4Wy4gMbE7e7a1WHLlZo4N0Y3CCI4yDdWRwgiOM,enr:-Iq4QNMYHuJGbnXyBj6FPS2UkOQ-hnxT-mIdNMMr7evR9UYtLemaluorL6J10RoUG1V4iTPTEbl3huijSNs5_ssBWFiGAYhBNHOzgmlkgnY0gmlwhIlKy_CJc2VjcDI1NmsxoQNULnJBzD8Sakd9EufSXhM4rQTIkhKBBTmWVJUtLCp8KoN1ZHCCIyk,enr:-Jq4QKOark9WXFRsOLx4RGwdYrH_YDiK39KP0niQ6D5gagX4Jo7ZxuzPwRN6YWedFhvlWP305qoDq8X4AmQ2PyyW3ukBhGV0aDKQzonDwWAAEBv__________4JpZIJ2NIJpcIRBbZouiXNlY3AyNTZrMaEDSZOVyosoT9D64UUw4_XiFapjaeCsvT0G5Zsnf81gyymDdWRwgiMp,enr:-Iq4QIc297-de1P6hznMX2cIdVsQkve9BD9NUsJ7vVQa7eh5UpekA9rLid5A-yLiS3gZwOGugYZPi58x76zNs2cEQFCGAYhBJlTYgmlkgnY0gmlwhEFtmi6Jc2VjcDI1NmsxoQJDyix-IHa_mVwLBEN9NeG8I-RUjNQK_MGxk9OqRQUAtIN1ZHCCIyg,enr:-OS4QPmu9RBpnkIciCJQCpTCdkZDUdp1Zl259VcYGGz1KinVa9dAWRxC-dK6X8vlRR1kffpQwkeLMzDE_nDtG05mVVYDh2F0dG5ldHOIAAMAAAAAAACGY2xpZW502IpMaWdodGhvdXNljDcuMC4wLWJldGEuN4RldGgykM6Jw8FgABAb__________-CaWSCdjSCaXCEp-sBuYRxdWljgiNRiXNlY3AyNTZrMaECRFTZ7g8SwCvj7Gwa7OSjBb51_pd0v--6Tbto_k9R6qSIc3luY25ldHMAg3RjcIIjUIN1ZHCCI1A ``` ## Step 4: Create a JWT Secret File This is required for Besu and Teku to talk over the Engine API: ```bash mkdir shared openssl rand -hex 32 > shared/token.txt ``` ## Step 5: Create docker-compose.yml Create a file named docker-compose.yml with this content: ```yaml --- version: "3.4" services: besu_node: image: hyperledger/besu:develop command: [ "--network=ephemery", "--bootnodes=${BOOTNODE_ENODE}", "--rpc-http-enabled=true", "--rpc-http-cors-origins=*", "--rpc-ws-enabled=true", "--host-allowlist=*", "--engine-host-allowlist=*", "--engine-rpc-enabled", "--engine-jwt-secret=/shared/token.txt", "--p2p-port=30303", "--p2p-host=0.0.0.0", ] volumes: - ./besu:/var/lib/besu/data - ./shared:/shared ports: # Map the p2p port(30303), RPC HTTP port(8545), and engine port (8551) - "8545:8545" - "8551:8551" - "30303:30303/tcp" - "30303:30303/udp" teku_node: environment: - "JAVA_OPTS=-Xmx4g" image: consensys/teku:develop command: [ "--network=https://ephemery.dev/latest/config.yaml", "--ee-endpoint=http://besu_node:8551", "--ee-jwt-secret-file=/shared/token.txt", "--metrics-enabled=true", "--rest-api-enabled=true", "--ignore-weak-subjectivity-period-enabled=true", "--checkpoint-sync-url=https://ephemery.beaconstate.ethstaker.cc/", "--p2p-advertised-ip=127.0.0.1", "--p2p-port=9000", "--p2p-discovery-bootnodes=${BOOTNODE_ENR_LIST}", ] depends_on: - besu_node volumes: - ./teku:/var/lib/teku/data - ./shared:/shared ports: # Map the p2p port(9000) and REST API port(5051) - "9000:9000/tcp" - "9000:9000/udp" - "5051:5051" ``` ## Step 6: Start Your Node Back in the project root inside `ephemery-node` folder, run: ```bash docker-compose up ``` Watch logs, you should see: ```Besu → “Starting synchronizer…” Teku → “Execution Client is online” Both → gradually “Connected peers: N > 0” Teku → “Syncing *** Slot: … Head slot: … Remaining slots: …” ``` Screenshots from logs on my running node: ![image (2)](https://hackmd.io/_uploads/Hkr86Lpvxl.png) ![image (3)](https://hackmd.io/_uploads/SJwJZwpPel.png) >[!Warning] >I've got this :point_down: error in the screenshot below when entered `ephemery` as network for Teku command options. so you better enter the url as the value for network. ![image](https://hackmd.io/_uploads/S1gAfDpvlx.png) Running Ephemery is a bit tricky here, at least for now. hopefully soon in future I will check into Teku codebase see why this error arises. >[!Tip] Some tips if you got problem with running with above inputs: - Running this command should show your head state and attestations. ```bash curl -s localhost:5051/eth/v1/beacon/states/head/finality_checkpoints ``` - Check your bootnodes / ENR_LIST are correct. - Ensure UDP/TCP ports (30303, 9000) are open in Docker and firewall. - Try explicit host IP instead of 0.0.0.0 or 127.0.0.1 for advertised-ip. - The valu for `engine-jwt-secret` should point at the same `/shared/token.txt`. - If no peer, copy and paste the values for `--bootnodes` and `--p2p-discovery-bootnodes` from the testnet-all folder directly into the docker-compose file. If you have any question I would be glad to help! Happy testing!🥳