Guide to Staking on Ethereum 2.0 Testnet (Ubuntu/Pyrmont/Teku)

WARNING — do not use this guide for connecting to the Eth2 Mainnet. Mainnet guides are here.

This is a step-by-step guide to staking on the Ethereum 2.0 Pyrmont multi-client testnet via the ConsenSys Teku client. It is based on the following technologies:

This guide includes instructions on how to:

  • Connect to and secure a newly running Ubuntu server instance
  • Configure and run an Ethereum 1.0 node as a service
  • Generate and fund Pyrmont validator account keys
  • Import Pyrmont validator account keys to Teku
  • Install and configure the Teku client software for Ethereum 2.0, Phase 0 (Pyrmont testnet) and run as a service
  • Install and configure Prometheus metrics and set up a Grafana dashboard

Warnings

This guide is written for the Pyrmont testnet. DO NOT, under any circumstances, send mainnet ETH to this testnet. You will lose it.

This guide SHOULD NOT be used for connecting to the Eth2 mainnet. An Eth2 mainnet specific guide can be found here.

Acknowledgements and Disclaimer

This guide is based on information I pulled together from various online resources and this guide wouldn’t exist without them. Thank you, all!

Thanks to the folks on the #teku channel on the ConsenSys Discord for their help and review!

Special thanks to the Teku client team and the EF researchers. Your tireless efforts over the past few years have brought us to the cusp of an incredible moment in history — the launch of Ethereum 2.0!

This guide is for educational purposes only. I’m not an expert in any of the technologies listed in this guide. The accuracy of this guide is not guaranteed and I am not responsible for any damages or losses incurred by following this guide.

Feedback is always welcome!

Support

This stuff can be tricky. If you need help there are two great resources you can reach out to (besides me):

  • EthStaker community on Reddit or Discord. Knowledgeable and friendly community passionate about staking on Ethereum 2.0.
  • Teku client team Discord. The client software engineering team. Experts on Teku and its usage.

Prerequisites

This guide assumes knowledge of Ethereum, ETH, staking, testnets, Linux, and MetaMask.

This guide also requires the following before getting started:

  • Ubuntu server v20.04 (LTS) amd64 or newer, installed and running on a local computer or in the cloud (AWS, Digital Ocean, Microsoft Azure, etc.). A local computer is encouraged for greater decentralization — if the cloud provider goes down then all nodes hosted with that provider go down.
  • MetaMask crypto wallet browser extension, installed and configured. A computer with a desktop (Mac, Windows, Linux) and a browser (Safari, Brave, FireFox, etc.) is required.

Note for Raspberry Pi Users

I haven’t tested this guide on a Rpi. If you want to try, just swap out the software listed below for the ARM version, where available. No guarantee it will work!

Requirements

  • Ubuntu server instance. I used v20.04 (LTS) amd64 server VM.
  • MetaMask crypto wallet browser extension, installed and configured.
  • Hardware requirements is a broad topic. In general a relatively modern CPU, 8GB RAM (16GB is better), a SSD of at least 1TB, and a stable internet connection with sufficient download speed and monthly data allowance are required for good staking performance on mainnet.

Overview

This is a long and detailed guide. Here’s a super-simplified diagram to help you conceptualize what we are going to do. The yellow boxes are the parts this guide mostly covers.

The conceptual flow is:

  • Set up a Eth1 Node and sync it with the Eth1 Blockchain (Göerli Testnet)
  • Generate the Validator Keys and Deposit Data
  • Configure the Teku client and sync it with the Eth1 Node
  • Deposit 32 Göerli Testnet ETH to activate the Validator Keys

Let’s get started!

Step 0 — Connect to the Server

Using a SSH client, connect to your Ubuntu server. The root user account on Ubuntu server is normally disabled by default, however some cloud providers enable it. If you are logged in as root then let’s create a user-level account with admin privileges instead, because using the root user to log in is risky.

# adduser <yourusername>

You will asked to create a password and some other information.

Grant admin rights to the new user by adding it to the sudo group.

# usermod -aG sudo <yourusername>

When you log in as <yourusername> you can type sudo before commands to perform actions with superuser privileges.

Optional: If you used SSH keys to connect to your Ubuntu instance via the root user you will need to associate the new user with the root user’s SSH key data.

# rsync --archive --chown=<yourusername>:<yourusername> ~/.ssh /home/<yourusername>

Finally, log out of root and log in as <yourusername>.

Step 1 — Update the Server

Make sure your system is up to date with the latest software and security updates.

$ sudo apt update && sudo apt upgrade
$ sudo apt dist-upgrade && sudo apt autoremove
$ sudo reboot

Step 2 — Secure the Server

Security is important. This is not a comprehensive security guide, just some basic settings: a firewall and a different SSH port.

Configure the firewall

Ubuntu 20.04 servers can use the default UFW firewall to restrict inbound traffic to the server. Before we enable it we need to allow inbound traffic for SSH, Go Ethereum, Grafana, and Teku.

Allow SSH
Allows connection to the server over SSH. For security reasons we are going to modify the default port of 22 because it is a common attack vector.

Choose a port number between 1024–49151 and run the following command to make sure your selection is not already in use on the server. If it is (red text), choose a different port. E.g. sudo ss -tulpn | grep ':6673'

$ sudo ss -tulpn | grep ':<yourSSHportnumber>'

Update the firewall to allow inbound traffic on <yourSSHportnumber>. SSH requires TCP. E.g. sudo ufw allow 6673/tcp

$ sudo ufw allow <yourSSHportnumber>/tcp

Next change the default SSH port.

$ sudo nano /etc/ssh/sshd_config

Find the line with # Port 22 or Port 22 and change it to Port <yourSSHportnumber>. Remove the # if it was present.

Check the screen shot below for reference. Your file should look similar to that (but with the port number you chose). Exit and save.

Restart the SSH service.

$ sudo systemctl restart ssh

Next time you log in via SSH use <yourSSHportnumber> for the port.

Optional: If you were already using UFW with port 22/TCP allowed then update the firewall to deny inbound traffic on that port. Only do this after you log in using the new SSH port.

$ sudo ufw deny 22/tcp

Allow Go Ethereum
Allows incoming requests from Go Ethereum peers (port 30303/TPC and 30303/UDP). If you’d rather use a node hosted by a 3rd party (Infura, etc.) then skip this step.

$ sudo ufw allow 30303

Allow Teku
Allows P2P connections with peers for actions on the beacon node. Ports 9000/TCP and 9000/UDP are listed as defaults by Consensys.

$ sudo ufw allow 9000

Allow Grafana
Allows incoming requests to the Grafana web server (port 3000/TCP).

$ sudo ufw allow 3000/tcp

Allow Prometheus (Optional)
If you want direct access to the Prometheus data service you can open up port 9090/TCP as well. This is not necessary if you are solely using Grafana to view the data. I did not open this port.

$ sudo ufw allow 9090/tcp

Enable the firewall and check to verify the rules have been correctly configured.

$ sudo ufw enable
$ sudo ufw status numbered

Output should look something like this:

Step 3 — Install and Run Go Ethereum Node

Install and configure an Ethereum 1.0 node that the beacon node will connect to. If you’d rather use a node hosted by a 3rd party (Infura, etc.) then skip this step.

Install Go Ethereum

Go Ethereum recommends using PPA’s (Personal Package Archives).

$ sudo add-apt-repository -y ppa:ethereum/ethereum

Update the packages and install the latest stable version.

$ sudo apt update
$ sudo apt install geth

Run Go Ethereum as a Background Service

Create an account for the service to run under. This type of account can’t log into the server.

$ sudo useradd --no-create-home --shell /bin/false goeth

Create the data directory for the Eth1 chain. This is required for storing the Eth1 node data.

$ sudo mkdir -p /var/lib/goethereum

Set directory permissions. The goeth account needs permission to modify the data directory.

$ sudo chown -R goeth:goeth /var/lib/goethereum

Create a systemd service file to store the service config. We will use the config file to tell systemd to run the geth process.

$ sudo nano /etc/systemd/system/geth.service

Paste the following service configuration into the file.

[Unit]
Description=Ethereum go client
After=network.target
Wants=network.target
[Service]
User=goeth
Group=goeth
Type=simple
Restart=always
RestartSec=5
ExecStart=geth --goerli --http --datadir /var/lib/goethereum
[Install]
WantedBy=default.target

The --goerli flag is used to target the Göerli test network and the --http flag exposes an endpoint (http://localhost:8545) that the beacon chain will connect to.

Check the screen shot below for reference. Your file should look like that. Exit and save.

Reload systemd to reflect the changes.

$ sudo systemctl daemon-reload

Start the service and check to make sure it’s running correctly.

$ sudo systemctl start geth
$ sudo systemctl status geth

Output should look like this:

If you did everything right, it should say active (running) in green text. If not then go back and repeat the steps to fix the problem. Press Q to quit.

Enable the geth service to automatically start on reboot.

$ sudo systemctl enable geth

The Go Ethereum node will begin to sync. You can follow the progress by running the journal command. Press Ctrl+C to quit.

$ sudo journalctl -fu geth.service

Sometimes it can take a while (>10 mins) to find peers to sync. If so, you can add some peers to help things along. Go here for the latest list and modify the geth service as follows:

$ sudo systemctl stop geth
$ sudo nano /etc/systemd/system/geth.service

Modify the ExecStart line and add the --bootnodes flag with a few of the latest peers (comma separated).

ExecStart=geth --goerli --http --datadir /var/lib/goethereum --bootnodes "enode://46add44b9f13965f7b9875ac6b85f016f341012d84f975377573800a863526f4da19ae2c620ec73d11591fa9510e992ecc03ad0751f53cc02f7c7ed6d55c7291@94.237.54.114:30313,enode://119f66b04772e8d2e9d352b81a15aa49d565590bfc9a80fe732706919f8ccd00a471cf8433e398c55c4862aadb4aadf3a010201483b87e8358951698aa0b6f07@13.250.50.139:30303"

Save the file and exit. Restart the service and observe.

$ sudo systemctl daemon-reload
$ sudo systemctl start geth
$ sudo journalctl -fu geth.service

Once it gets started the output should look like this:

You should wait for the node sync to fully complete before you run the beacon chain. You can see the latest block here.

For example, the screen shot above shows the node is processing block number=43756 and looking at the screen shot below, we can see the latest block number is 3196411. So based on that we still have a while to go before completing the sync.

Next we will prepare the validator deposit data. If you want to check the status of the sync you can do so at any time by running sudo journalctl -fu geth.service.

Step 4 — Generate Validator Keys and Deposit Data

In order to run a validator on the Pyrmont testnet we will need to sign up for one or more validator accounts.

The steps to sign-up are:

  • Get Göerli ETH
  • Generate the validator keys. Each key is a validator account
  • Fund the validator account(s) (32 Göerli ETH per account)
  • Wait for your validator account(s) to become active

Let’s get started.

Get Goerli ETH

  1. Go to a computer with the MetaMask browser extension installed.
  2. Click on MetaMask and log in.
  3. Using the dropdown at the top, select the Göerli Test Network.
  4. Click on the account name to copy your Göerli ETH wallet address.
  5. Using your address, get Göerli ETH from the authenticated faucet or via the #request-goerli-eth channel on the ethstaker Discord using the bot command: !goerliEth <yourwalletaddress>.

Generate Validator Keys

Next we will generate the deposit data and validator keys. The Teku validator client supports multiple validator keys. Each validator key is basically a “validator account” on the Pyrmont testnet. The deposit data has information about your staking deposit (list of validator keys, etc.).

Go here to get the “Latest release” of the deposit command line interface app.

On the page in the assets section copy the link to the Linux version. Be sure you copy the correct link. We will use that link to download it as shown below. Modify the URL name in the instructions below to match the latest version download link.

$ cd ~
$ sudo apt install curl
$ curl -LO https://github.com/ethereum/eth2.0-deposit-cli/releases/download/v1.1.0/eth2deposit-cli-ed5a6d3-linux-amd64.tar.gz

Unpack the tar archive and go into the directory it created.

$ sudo tar xvf eth2deposit-cli-ed5a6d3-linux-amd64.tar.gz
$ cd eth2deposit-cli-ed5a6d3-linux-amd64

Run the application to generate the deposit data and validator keys.

Change <numberofvalidators> to the number of validator keys you want to create. E.g. --num_validators 5.

$ sudo ./deposit new-mnemonic --num_validators <numberofvalidators> --mnemonic_language=english --chain pyrmont

It will ask you to create a validator keystore password. Back it up somewhere safe. This is critical. We will use this later to load the validator keys into Teku’s validator wallet.

A seed phrase (mnemonic) will be generated. Back it up somewhere safe. This is critical. You will eventually use this to generate your withdrawal keys or add additional validators.

Once you have confirmed your mnemonic your validator keys will be created.

The newly created validator keys and deposit data file are created at the specified location. E.g. eth2deposit-cli-ed5a6d3-linux-amd64/validator_keys. Make a note of this. We will need it later.

The contents of the folder are shown below.

The deposit_data-[timestamp].json file contains the public keys for the validators and information about the deposit. This file will be used to complete the deposit process later on. Since we are on a server we don’t have a web browser so secure FTP (SFTP) the file over to a computer running MetaMask. Do this before you continue.

The keystore-m...json files contain the encrypted signing key. There is one keystore-m per validator. These will be imported into Teku’s validator wallet.

Clean up by removing the downloaded tar archive file.

$ cd ~
$ rm -rf eth2deposit-cli-ed5a6d3-linux-amd64.tar.gz

Now that we have the deposit data and the keystore files we will move on to set up Teku. We will do this before funding the keys (depositing the Göerli ETH to activate the validators) so we can verify the set up first. If the validator deposits become active and the system is not ready we will start receiving penalties for non-activity.

Step 5 — Install Prerequisites

Teku is built using Java so it requires the Java runtime (JRE) to run and the Java development kit (JDK) to compile.

Install them both and confirm the installations.

$ sudo apt install default-jre default-jdk
$ java --version
$ javac --version

Output should be similar to this.

ethstaker@ETH-STAKER-001:~$ java --version
openjdk 11.0.9.1 2020-11-04
OpenJDK Runtime Environment (build 11.0.9.1+1-Ubuntu-0ubuntu1.20.04)
OpenJDK 64-Bit Server VM (build 11.0.9.1+1-Ubuntu-0ubuntu1.20.04, mixed mode, sharing)
ethstaker@ETH-STAKER-001:~$ javac --version
javac 11.0.9.1

Step 6 — Clone and Build Teku

Now we’re ready to build Teku. The Teku build produces a teku binary. The binary provides the functionality of the beacon node and validator client.

First go here to determine the latest release of Teku. It is important to avoid cloning the master branch as it may be unstable.

Use the label (in this case 20.11.0-RC2).

$ cd ~
$ git clone -b 20.11.0-RC2 https://github.com/Consensys/teku.git
$ cd teku

Compile the code using Gradle.

$ sudo ./gradlew installDist

The build is reasonably quick (3–6 minutes). While building it’s a good time to get a fresh beverage and hydrate. Maybe check out a few of my other articles.

If the build succeeds then continue. If not get help in the #teku channel on the ConsenSys Discord.

Step 7 — Copy the Teku Binary

Next, copy the compiled Teku files to the /usr/local/bin directory. We will create a systemd service later to run it from there.

$ cd ~
$ sudo cp -a teku/build/install/teku/. /usr/local/bin/teku

Step 8 — Configure the Beacon Node and Validator

We will run Teku as a service so if the system restarts the process will automatically start back up again.

Setup Accounts and Directories

Create an account for the beacon node and validator to run under. This type of account can’t log into the server.

$ sudo useradd --no-create-home --shell /bin/false teku

Create the data directory for the Teku data files and the config directory for the Teku configuration files.

$ sudo mkdir -p /var/lib/teku
$ sudo mkdir -p /etc/teku

So we can keep things in one place, copy the keystore-m...json files to the data directory we created above.

$ sudo cp -a /$HOME/<ValidatorKeysPath> /var/lib/teku

Replace <ValidatorKeysPath> with the path to your generated validator keys. E.g. eth2deposit-cli-ed5a6d3-linux-amd64/validator_keys. The important thing is that we only copy the keystore-m files. Do not copy over the deposit_data file. If you do, simply delete it using this:

$ cd /var/lib/teku/validator_keys
$ ls
$ sudo rm <DepositDataFileName>

It should look like this (depending on how many validator files you have):

Create the Validator Password File(s)

Teku requires validator a password file in order to access each validator account when running and automatically restarting the service.

For each validator keystore-m...json key file a corresponding password txt file is required. This is true even if the password is the same for each validator. The password file will need to be named to match the corresponding keystore-m file.

First get a listing of the keystore files.

$ ls /var/lib/teku/validator_keys

For each keystore_m*.json file, create an equivalently named password file.

$ sudo nano /var/lib/teku/validator_keys/<jsonfilename>.txt

Replace <jsonfilename> with the name of the json file. Don’t forget to add the .txt at the end.

Within the txt file, replace YourKeystorePasswordForThisValidator with the keystore password (the one you provided when creating the validator files in Step 4). Save and exit. Repeat this sequence for each *.json file.

It should look like this when you are done.

Set Permissions

Set directory permissions. The teku account needs permission to modify the data directory. Verify directory permissions are set correctly.

$ sudo chown -R teku:teku /var/lib/teku
$ sudo chown -R teku:teku /etc/teku
$ ls -dl /var/lib/teku; ls -dl /etc/teku

Should look like this:

Apply file permissions to the validator keys to provide an extra layer of security and to prevent accidental deletion. Grants read/write/execute to the user (teku). Verify the file permissions are set correctly.

$ sudo chmod -R 700 /var/lib/teku/validator_keys
$ sudo ls -lh /var/lib/teku/validator_keys

Should look like this:

Now that we have the validator keys and passwords set up let’s configure the service itself.

Create the Teku Configuration File

Teku can read command line options via a configuration file. Let’s create it.

$ sudo nano /etc/teku/teku.yaml

Paste the following into the file.

data-base-path: "/var/lib/teku"network: "pyrmont"eth1-endpoint: "http://127.0.0.1:8545/"validator-keys: "/var/lib/teku/validator_keys:/var/lib/teku/validator_keys"validators-graffiti: "<yourPOAPstring>"p2p-port: 9000log-destination: CONSOLEmetrics-enabled: true
metrics-port: 8008
rest-api-enabled: true
rest-api-docs-enabled: true

The data-base-path defines the location where the service stores data.

The eth1-endpoint defines the endpoint of the Eth1 node. If you installed one locally the value is http://127.0.0.1:8545. If you’re using a third party endpoint (e.g. Infura, etc.) change the value to point to the external endpoint address.

The validators-keys is the location of the key files and password files. In this case they are located in the same directory.

Replace <yourPOAPstring> with your preferred text. E.g. validators-graffiti: "abcdefg12345"

The log-destination: CONSOLE setting is recommended for systemd usage.

Check the screen shot below for reference. Your file should look similar to that. Exit and save.

Create and Configure the Teku Service

Create a systemd service file to store the service config.

$ sudo nano /etc/systemd/system/teku.service

Paste the following into the file.

[Unit]
Description=Teku Client
Wants=network-online.target
After=network-online.target
[Service]
Type=simple
User=teku
Group=teku
Restart=always
RestartSec=5
Environment="JAVA_OPTS=-Xmx2g"
ExecStart=/usr/local/bin/teku/bin/teku --config-file=/etc/teku/teku.yaml
[Install]
WantedBy=multi-user.target

The Java (programming language Teku was written in) execution runtime uses up a lot of RAM by design. The Environment=”JAVA_OPTS=-Xmx2g” limits the available heap size to 2GB, and results in a total process size of around 3–3.5GB for the Teku process.

Check the screen shot below for reference. Your file should look like that. Exit and save.

Reload systemd to reflect the changes.

$ sudo systemctl daemon-reload

Start the service and check to make sure it’s running correctly.

$ sudo systemctl start teku
$ sudo systemctl status teku

Output should look like this.

If you did everything right, it should say active (running) in green text. If not then go back and repeat the steps to fix the problem. Press Q to quit.

Enable the service to automatically start on reboot.

$ sudo systemctl enable teku

The beacon node will begin to sync. It may take several hours for the node to fully sync. You can check the progress by running the journal command. Press Ctrl+C to quit.

$ sudo journalctl -fu teku.service

It will start to process validator keys and then sync to the Eth1 chain head. Once Head slot reaches Current slot the beacon node is synced.

Started Teku Client.
...
INFO - Loading 2 validator keys...
INFO - BLS: loaded BLST library
INFO - Loaded 2 Validators: 96a349b, b7f51b6
...
INFO - Sync Event *** Current slot: 30174, Head slot: 54, Connected peers: 1
INFO - Sync Event *** Current slot: 30175, Head slot: 92, Connected peers: 6
INFO - Sync Event *** Current slot: 30176, Head slot: 128, Connected peers: 8
INFO - Sync Event *** Current slot: 30177, Head slot: 160, Connected peers: 10

That’s it. We have a functioning beacon node and validator. Congratulations: you are awesome!

Step 9 — Fund the Validator Keys

Now that your set up is up and running, to actually stake on the Pyrmont testnet you will need to deposit your 32 Göerli ETH.

This step involves depositing the required amount of Göerli ETH to the Pyrmont testnet staking contract. This is done in a web browser running MetaMask via the Eth2.0 Launchpad website.

Go here: https://pyrmont.launchpad.ethereum.org/

Click through the warning steps and continue through the screens until you get to the Generate Key Paris section. Select the number of validators you are going to run. Choose a value that matches the number of validators you created in Step 4.

Scroll down, check the box, and click continue.

You will be asked to upload the deposit_data-[timestamp].json file. We generated this file earlier in the guide, and copied it to the computer with the web browser. Browse or drag the file and click continue.

Connect your wallet. Choose MetaMask, log in, select the account where you have your Göerli ETH on the Göerli Test Network and click Continue.

Your MetaMask balance will be displayed. The site will allow you to continue if you have selected the Göerli Test Network and you have sufficient Göerli ETH balance.

A summary shows the number of validators and total amount of Göerli ETH required. Tick the boxes if you agree and click continue.

Click on Initiate All Transactions.

This will pop open multiple instances of MetaMask, each with a 32 Göerli ETH transaction request to the Pyrmont testnet deposit contract. Confirm each transaction.

Once all the transactions have successfully completed you are done!

Congratulations are due!

There is a checklist at the end of the process. Lots of good information there. Take a look.

Check the Status of Your Validators

Newly added validators can take a while (hours to days) to activate. You can check the status of your keys with these steps:

  1. Copy your Göerli Test Network MetaMask wallet address.
  2. Go here: https://pyrmont.beaconcha.in/
  3. Search for your key(s) using your wallet address.

Digging into a specific validator we see a Status that provides an estimate until activation for each validator.

That’s it. We have a functioning beacon-chain and validator and our testnet deposit is in. Once your deposit is active you will begin staking and earning rewards. Congratulations: you are awesome!

Step 10— Install Prometheus

Prometheus is an open-source systems monitoring and alerting toolkit. It runs as a service on your Ubuntu server and its job is to capture metrics. More information here.

We are going to use Prometheus to expose runtime data from the beacon node and validator as well as instance specific metrics.

Create User Accounts

Accounts for the services to run under. These accounts can’t log into the server.

$ sudo useradd --no-create-home --shell /bin/false prometheus
$ sudo useradd --no-create-home --shell /bin/false node_exporter

Create Directories

Program and data directories.

$ sudo mkdir /etc/prometheus
$ sudo mkdir /var/lib/prometheus

Set directory ownership. The prometheus account will manage these.

$ sudo chown -R prometheus:prometheus /etc/prometheus
$ sudo chown -R prometheus:prometheus /var/lib/prometheus

Download Prometheus software

Adjust the version number to the latest version from the Prometheus download page. Rpi users be sure to get the ARM binary.

$ cd ~
$ curl -LO https://github.com/prometheus/prometheus/releases/download/v2.22.2/prometheus-2.22.2.linux-amd64.tar.gz

Unpack the archive. It contains two binaries and some content files.

$ tar xvf prometheus-2.22.2.linux-amd64.tar.gz

Copy the binaries to the following locations.

$ sudo cp prometheus-2.22.2.linux-amd64/prometheus /usr/local/bin/
$ sudo cp prometheus-2.22.2.linux-amd64/promtool /usr/local/bin/

Set directory ownership. The prometheus account will manage these.

$ sudo chown -R prometheus:prometheus /usr/local/bin/prometheus
$ sudo chown -R prometheus:prometheus /usr/local/bin/promtool

Copy the content files to the following locations.

$ sudo cp -r prometheus-2.22.2.linux-amd64/consoles /etc/prometheus
$ sudo cp -r prometheus-2.22.2.linux-amd64/console_libraries /etc/prometheus

Set directory and file (-R) ownership. The prometheus account will manage these.

$ sudo chown -R prometheus:prometheus /etc/prometheus/consoles
$ sudo chown -R prometheus:prometheus /etc/prometheus/console_libraries

Remove the downloaded archive.

$ rm -rf prometheus-2.22.2.linux-amd64.tar.gz prometheus-2.22.2.linux-amd64

Edit the Configuration File

Prometheus uses a configuration file so it knows where to scrape the data from. We will set this up here.

Open the YAML config file for editing.

$ sudo nano /etc/prometheus/prometheus.yml

Paste the following into the file taking care not to make any additional edits and exit and save the file.

global:
scrape_interval: 15s
scrape_configs:
- job_name: "prometheus"
static_configs:
- targets: ["localhost:9090"]
- job_name: "teku"
scrape_timeout: 10s
metrics_path: /metrics
scheme: http
static_configs:
- targets: ["localhost:8008"]

Set ownership for the config file. The prometheus account will own this.

$ sudo chown -R prometheus:prometheus /etc/prometheus/prometheus.yml

Finally, let’s test the service is running correctly.

$ sudo -u prometheus /usr/local/bin/prometheus \
--config.file /etc/prometheus/prometheus.yml \
--storage.tsdb.path /var/lib/prometheus/ \
--web.console.templates=/etc/prometheus/consoles \
--web.console.libraries=/etc/prometheus/console_libraries

Output should look something like this. Press Ctrl + C to exit.

level=info ts=2020-11-22T17:24:35.396Z caller=main.go:684 msg="Server is ready to receive web requests."

Set Prometheus to Auto-Start as a Service

Create a systemd service file to store the service config which tells systemd to run Prometheus as the prometheus user, with the configuration file located in the /etc/prometheus/prometheus.yml directory, and to store its data in the /var/lib/prometheus directory.

$ sudo nano /etc/systemd/system/prometheus.service

Paste the following into the file. Exit and save.

[Unit]
Description=Prometheus
Wants=network-online.target
After=network-online.target
[Service]
Type=simple
User=prometheus
Group=prometheus
Restart=always
RestartSec=5
ExecStart=/usr/local/bin/prometheus \
--config.file /etc/prometheus/prometheus.yml \
--storage.tsdb.path /var/lib/prometheus/ \
--web.console.templates=/etc/prometheus/consoles \
--web.console.libraries=/etc/prometheus/console_libraries
[Install]
WantedBy=multi-user.target

Reload systemd to reflect the changes.

$ sudo systemctl daemon-reload

And then start the service with the following command and check the status to make sure it’s running correctly.

$ sudo systemctl start prometheus
$ sudo systemctl status prometheus

Output should look something like this:

If you did everything right, it should say active (running) in green. If not then go back and repeat the steps to fix the problem. Press Q to quit.

Lastly, enable Prometheus to start on boot.

$ sudo systemctl enable prometheus

Step 11 — Install Node Exporter

Prometheus will provide metrics about the beacon chain and validators. If we want metrics about our Ubuntu instance, we’ll need an extension called Node_Exporter. You can find the latest stable version here if you want to specify a different version below. Rpi users remember to get the ARM binary.

$ cd ~
$ curl -LO https://github.com/prometheus/node_exporter/releases/download/v1.0.1/node_exporter-1.0.1.linux-amd64.tar.gz

Unpack the downloaded software.

$ tar xvf node_exporter-1.0.1.linux-amd64.tar.gz

Copy the binary to the /usr/local/bin directory and set the user and group ownership to the node_exporter user we created above.

$ sudo cp node_exporter-1.0.1.linux-amd64/node_exporter /usr/local/bin
$ sudo chown -R node_exporter:node_exporter /usr/local/bin/node_exporter

Remove the downloaded archive.

$ rm -rf node_exporter-1.0.1.linux-amd64.tar.gz node_exporter-1.0.1.linux-amd64

Set Node Exporter to Auto-Start as a Service

Create a systemd service file to store the service config which tells systemd to run Node_Exporter as the node_exporter user.

$ sudo nano /etc/systemd/system/node_exporter.service

Paste the following into the file. Exit and save.

[Unit]
Description=Node Exporter
Wants=network-online.target
After=network-online.target
[Service]
User=node_exporter
Group=node_exporter
Type=simple
ExecStart=/usr/local/bin/node_exporter
[Install]
WantedBy=multi-user.target

Reload systemd to reflect the changes.

$ sudo systemctl daemon-reload

And then start the service with the following command and check the status to make sure it’s running correctly.

$ sudo systemctl start node_exporter
$ sudo systemctl status node_exporter

Output should look something like this:

If you did everything right, it should say active (running) in green. If not then go back and repeat the steps to fix the problem. Press Q to quit.

Finally, enable Node Exporter to start on boot.

$ sudo systemctl enable node_exporter

Test Prometheus and Node Exporter (Optional)

Everything should be ready to go. You may optionally test the functionality by opening a port in the firewall (see Step 1) and browsing to http://<yourserverip>:9090. From there you can run queries to view different metrics. For example try this query to see how much memory is free in bytes:

http://<yourserverip>:9090/new/graph?g0.expr=node_memory_MemFree_bytes&g0.tab=1&g0.stacked=0&g0.range_input=1h

Step 12 — Install Grafana

While Prometheus is our data source, Grafana is going provide our reporting dashboard capability. Let’s install it and configure a dashboard.

We will install using an APT repository because it is easier to install and update. Grafana is available in the official Ubuntu packages repository, however the version of Grafana there may not be the latest, so we will use Grafana’s official repository.

Download the Grafana GPG key with wget, then pipe the output to apt-key. This will add the key to your APT installation’s list of trusted keys.

$ wget -q -O - https://packages.grafana.com/gpg.key | sudo apt-key add -

Add the Grafana repository to the APT sources.

$ sudo add-apt-repository "deb https://packages.grafana.com/oss/deb stable main"

Refresh the apt cache.

$ sudo apt update

Make sure Grafana is installed from the repository.

$ apt-cache policy grafana

Output should look like this:

grafana:
Installed: (none)
Candidate: 7.3.3
Version table:
7.3.3 500
500 https://packages.grafana.com/oss/deb stable/main amd64 Packages
7.3.2 500
500 https://packages.grafana.com/oss/deb stable/main amd64 Packages
7.3.1 500
500 https://packages.grafana.com/oss/deb stable/main amd64
...

Verify the version at the top matches the latest version shown here. Then proceed with the installation.

$ sudo apt install grafana

Start the Grafana server and heck the status to make sure it’s running correctly.

$ sudo systemctl start grafana-server
$ sudo systemctl status grafana-server

Output should look something like this:

If you did everything right, it should say active (running) in green. If not then go back and repeat the steps to fix the problem. Press Q to quit.

Enable Grafana to start on boot.

$ sudo systemctl enable grafana-server

Configure Grafana Login

Great job on getting this far! Now that you have everything up and running you can go to http://<yourserverip>:3000/ in a browser and the Grafana login screen should come up.

Enter admin for the username and password. It will prompt you to change your password and you should definitely do that.

Configure the Grafana Data Source

Let’s configure a datasource. Move your mouse over the gear icon on the left menu bar. A menu will pop-up — choose Data Sources.

Add data source screen.
Add data source screen.

Click on Add data source and then choose Prometheus. Enter http://localhost:9090 for the URL then click on Save and Test.

Data source configuration.
Data source configuration.
Data source is confirmed working.
Data source is confirmed working.

Import a Grafana Dashboard

Now let’s import a dashboard. Move your mouse over the + icon on the left menu bar. A menu will pop-up - choose Import.

Use the code 13457 to import the official Teku single validator dashboard or use code 12522 to import Ben Edgington’s dashboard.

You may also need to select the datasource (Prometheus).

You should be able to view the dashboard. At first you may not have sufficient data, but after everything gets going the data will populate.

Final Remarks

Okay… That’s it! We are done! I hope you enjoyed this guide.

  • If you have feedback you can reach me on Twitter or Reddit.
  • If you liked this guide and think others would benefit from it then please share it using the friends link!
  • Tips: somer.eth

Appendix — Updating Teku

If the Teku client team updates the code in the Teku repository you can update the service by using the following commands.

Replace <release> with the desired release as listed here. E.g. $ git fetch --tags && git checkout 20.11.0-RC2.

$ cd ~
$ cd teku
$ sudo git fetch --tags && git checkout <release>
$ sudo ./gradlew installDist
$ sudo systemctl stop teku
$ sudo rm -r /usr/local/bin/teku # <-- Delete old build
$ sudo cp -a ~/teku/build/install/teku/. /usr/local/bin/teku
$ sudo systemctl start teku
$ sudo systemctl status teku # <-- Check status
$ sudo journalctl -fu teku # <-- Check status

Passionate about Ethereum and decentralized technology.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store