Guide to Staking on Ethereum 2.0 (Ubuntu/Medalla/Teku)

***
NOTE: This guide is now deprecated. Please use the newer version targeting the Pyrmont testnet.
*** located here.
This is a step-by-step guide to staking on the Ethereum 2.0 Medalla multi-client testnet via the PegaSys Teku client. It is based on the following technologies:
- Ubuntu v20.04 (LTS) x64 server
- Go Ethereum Node (code branch)
- PegaSys’ Ethereum 2.0 client, Teku (code branch)
- Official multi-client testnet public network, Medalla
- MetaMask crypto wallet browser extension
- Prometheus metrics
- Grafana dashboard
This guide includes instructions on how to:
- Configure a newly running Ubuntu server instance.
- Configure and run an Ethereum 1.0 node as a service.
- Generate and process Medalla validator account keys.
- Compile and configure the Teku client software for Ethereum 2.0, Phase 0 (Medalla testnet) and run as a service.
- Install and configure Prometheus metrics and set up a Grafana dashboard.
WARNING
This guide is for the Medalla testnet. DO NOT, under any circumstances, send real ETH to this testnet. You will lose it.
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!
Special thanks go to the folks on the #teku channel on the ConsenSys Discord for their help and review!
And a special Thank You to the 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 is for educational purposes only. I’m not an expert in any of the technologies listed in this guide. I got it working and it’s a lot of fun, so I wanted to share it with others. Please forgive any errors or ill-informed choices. The accuracy of this guide is not guaranteed. Feedback is always welcome!
Prerequisites
This guide is not intended for absolute beginners. It assumes some knowledge of Ethereum, ETH, staking, Linux, and MetaMask. Before you get started you will need to have your Ubuntu server instance up and running. It will help to have the MetaMask browser extension installed and configured somewhere. The rest we will do along the way.
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 are currently undefined. I used a VM with the following specs:
- Intel(R) Xeon(R) Gold 6140 CPU @ 2.30GHz
- 4 GB RAM
- 80GB SSD
Overview
This is a long and detailed guide. The simplified diagram below may help conceptualize what we are going to do. The yellow boxes are the parts this guide mostly covers.
For now the Teku client runs as a single instance for both the Beacon Node and Validator Client functionality. The team is working on separating the client into two processes. The diagram shows the latter in anticipation of the change.

The conceptual flow is:
- Set up a Eth1 node and sync it with the Eth1 Goerli testnet
- Generate and activate validator keys
- Configure the beacon node and validator
- The beacon chain makes the magic happen (blocks, proposals, attestations, slashings) with the help of the validator (signing).
***
NOTE: This guide is now deprecated. Please use the newer version targeting the Pyrmont testnet.
*** located here.
Step 1 — Secure Your System
Security is important. This is not a comprehensive security guide, rather just some basic settings: a firewall and a user account. This assumes you have console access to your Ubuntu instance and are logged in via SSH as the root
user.
Configure the firewall
Ubuntu 20.04 servers can use the default UFW firewall to restrict traffic to the server. We need to allow inbound traffic for SSH, Go Ethereum, Grafana, and Teku.
Allow SSH — Allows connection to the server over SSH (port 22/TCP).
Note: For security reasons, you may want to consider changing your SSH port to something other than the default of 22. There are some nuances that go with that, so do you research.
# ufw allow 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.
Note: If you are hosting your Ubuntu instance locally your internet router and/or firewall will need to be configured to allow incoming traffic on these ports as well.
# ufw allow 30303/tcp
# ufw allow 30303/udp
Allow Teku — Allows P2P connections with peers for actions on the beacon node (ports 9001/TCP and 9001/UDP).
Note: If you are hosting your Ubuntu instance locally your internet router and/or firewall will need to be configured to allow incoming traffic on these ports as well.
# ufw allow 9001/tcp
# ufw allow 9001/udp
Allow Grafana — Allows incoming requests to the Grafana web server (port 3000/TCP).
# ufw allow 3000/tcp
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.
# ufw allow 9090/tcp
Now enable the firewall and check to verify the rules have been correctly configured.
# ufw enable
# ufw status numbered
Output should look something like this.

Create a new user and grant administrative privileges
Using the root user to log in is risky. Let’s create a user-level account with admin privileges instead.
# 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 are using SSH keys to connect to your instance (recommended for better security) you will need to associate <yourusername>
with the root
user’s SSH key data.
# rsync --archive --chown=<yourusername>:<yourusername> ~/.ssh /home/<yourusername>
Step 2 — Update Your System
Log out of root
and SSH into your Ubuntu instance with your newly created user account and apply the following commands to update the system.
$ sudo apt update && sudo apt upgrade
$ sudo apt dist-upgrade && sudo apt autoremove
***
NOTE: This guide is now deprecated. Please use the newer version targeting the Pyrmont testnet.
*** located here.
Step 3 — Install and Run Go Ethereum Node
Install and configure an Ethereum 1.0 node that the Teku 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 ethereum
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 -f -u 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 -f -u 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. Consider opening a new terminal session here so you can continue to observe the Eth1 node sync in the existing session.
Step 4— Prepare the Validator Deposit Data
In order to run a validator on the Eth2.0 Medalla testnet we will need to sign up for one or more validator accounts.
Note: If you have already generated your deposit data and submitted your staking deposits you can skip this step. This guide assumes the files are stored on the Ubuntu server here:
$HOME/eth2.0-deposit-cli/validator_keys
.
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
- Go to a computer with the MetaMask browser extension installed.
- Click on MetaMask and log in.
- Using the dropdown at the top, select the Göerli Test Network.
- Click on the account name to copy your Göerli ETH wallet address.
- 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>
.
Note: Each validator requires a 32 ETH deposit. You should have sufficient Göerli ETH in your MetaMask wallet to fund each validator. For example, if you want 10 validators you need to have 320 Göerli ETH plus some extra (e.g. 1 Göerli ETH) to pay for the gas fees.
Generate Validator Keys
Next we will generate the validator keys. The Teku validator client supports multiple validator keys. Each validator key is basically a “validator account” on the Medalla testnet.
Clone the deposit generator client.
$ cd ~
$ git clone https://github.com/ethereum/eth2.0-deposit-cli.git
$ cd eth2.0-deposit-cli
Check the Python version (Python 3.7 and above is required).
$ python3 -V
If you don’t have Python (or have a version below 3.7), follow these steps.
$ sudo apt install software-properties-common
$ sudo add-apt-repository ppa:deadsnakes/ppa
$ sudo apt update
$ sudo apt install python3.7
Install the prerequisites.
$ sudo apt install python3-pip
Install the application to generate the validator keys.
Change <numberofvalidators>
to the number of validator keys you want to create. E.g. --num_validators 5
.
$ sudo ./deposit.sh install
$ ./deposit.sh new-mnemonic --num_validators <numberofvalidators> --mnemonic_language=english --chain medalla
After running this step you should have a deposit JSON file, some validator key JSON files, a password, and a mnemonic seed phrase. You should back up all of these somewhere safe.
Success!
Your keys can be found at: /home/<yourusername>/eth2.0-deposit-cli/validator_keys
Copy Deposit Data File
In the validator_keys
directory there will be a deposit_data-[timestamp].json
file. You will need to upload this via a website in the next step. Since we are on a server, we don’t have a web browser so secure FTP (SFTP) the file to a desktop computer that does.
Fund the Validator Keys
This step involves depositing the required amount of Göerli ETH to the Medalla testnet staking contract. This is done on the Eth2.0 Lauchpad website.
WARNING: DO NOT send real ETH to the Medalla testnet. You will lose your ETH.
Go here: https://medalla.launchpad.ethereum.org/
Click through the warning steps then select the number of validators you are going to run. Scroll down and click continue.

You will be asked to upload the deposit_data-[timestamp].json
file. Browse or drag the file and click continue.

Connect your wallet. Choose MetaMask, log in, select the Göerli Test Network and click Continue.
WARNING: Be absolutely 100% sure you have selected the Göerli Test Network in MetaMask. DO NOT sent real ETH to the Medalla testnet.

Your MetaMask balance will be displayed. The site will allow you to continue if 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 Medalla testnet deposit contract. Confirm each transaction.

Once all the transactions have successfully completed you are done!

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:
- Find your public key(s) in the
deposit_data-[timestamp].JSON
file. - Go here: https://medalla.beaconcha.in/
- Search for your key(s).
Estimated Activation provides the duration and epoch to activation.

That’s it! Now let’s build and configure the beacon chain and validator client.
***
NOTE: This guide is now deprecated. Please use the newer version targeting the Pyrmont testnet.
*** located here.
Step 5— Install Dependencies
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
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.
Note: The PegaSys team are currently working on separating the binary into beacon node and validator binaries.
Clone the Teku Github repository.
$ cd ~
$ sudo git clone https://github.com/PegaSysEng/teku.git
$ cd teku
Compile the code using Gradle.
$ sudo ./gradlew installDist
If the build succeeds then continue. If not get help in the #teku channel on the ConsenSys Discord.
Step 7 — Copy Teku Build Output
Copy the contents of the build output to the usr/local/teku
directory where we will run Teku as a service.
sudo cp -a ~/teku/build/install/teku/. /usr/local/teku
Note: You will need to do this step each time you pull latest code and build a new version of the Teku binary.
***
NOTE: This guide is now deprecated. Please use the newer version targeting the Pyrmont testnet.
*** located here.
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
Set directory permissions. The teku
account needs permission to modify the data directory.
$ sudo chown -R teku:teku /var/lib/teku
$ sudo chown -R teku:teku /etc/teku
So we can keep things in one place, copy the validator_files
directory to the data directory we created above.
$ sudo cp -a /$HOME/eth2.0-deposit-cli/validator_keys /var/lib/teku
Create a Validator Password File
Teku requires a validator password file to access the validator accounts.
$ sudo nano /etc/teku/validators-password.txt
Add the password you used when creating the validators in Step 4 to the file. Save and exit.

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-path: "/var/lib/teku"network: "medalla"eth1-endpoint: "http://127.0.0.1:8545/"validators-key-files: [
"/var/lib/teku/validator_keys/keystore-m_*.json",
"/var/lib/teku/validator_keys/keystore-m_*.json",
...
"/var/lib/teku/validator_keys/keystore-m_*.json",
"/var/lib/teku/validator_keys/keystore-m_*.json"
]validators-key-password-files: [
"/etc/teku/validators-password.txt",
"/etc/teku/validators-password.txt",
...
"/etc/teku/validators-password.txt",
"/etc/teku/validators-password.txt"
]validators-graffiti: "<yourPOAPstring>"p2p-port: 9001log-destination: CONSOLEmetrics-enabled: true
metrics-port: 8008rest-api-enabled: true
rest-api-docs-enabled: true
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 change the value to point to the external endpoint address.
The validators-key-files
lists the validator file names in the /var/lib/teku/validator_keys
directory. You can copy the file names from a second terminal window:
$ cd /var/lib/teku/validator_keys
$ ls
The validators-key-password-files
is the password file we created earlier. You will need one password file per validator key, even if the password is the same for each. If you have 10 validator keys, you need to list 10 validator password files.
Replace <yourPOAPstring>
with your Teku POAP participation medal value for a special NFT prize! E.g.: validators-graffiti: "abc123abc123def"
.
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 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 Beacon Node
Wants=network-online.target
After=network-online.target[Service]
Type=simple
User=teku
Group=teku
Restart=always
RestartSec=5
ExecStart=/usr/local/teku/bin/teku -c /etc/teku/teku.yaml[Install]
WantedBy=multi-user.target
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
Note: If you are running a local Eth1 node (see Step 3) you should wait until it fully syncs before starting the teku service. Check progress here:
sudo journalctl -f -u geth.service
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 -f -u teku.service
It will start to process validator keys and then sync to the Eth1 chain head. Once Current slot
reaches Head slot
the beacon node is synced.
Started Teku Beacon Node.
INFO Configuring logging for destination: console
INFO Logging includes events: true
INFO Logging includes validator duties: true
INFO Logging includes color: true
INFO - Teku version: teku/v0.12.3-dev-1b9be173/linux-x86_64/-ubuntu-openjdk64bitservervm-java-11
INFO - Loading 9 validator keys...
INFO - Successfully loaded native BLS library
INFO - Loaded 9 Validators: 80fafaf, b250168, a39fe65, acdfd94, 84bfa11, 80720b3, a240cb7, 845b9e0, b033401
INFO - Using default implementation for ThreadExecutor
INFO - Job execution threads will use class loader of thread: main
...
INFO - Using data path: /var/lib/teku
INFO - Starting metrics http service on 127.0.0.1:8008
INFO - Data directory set to: /var/lib/teku
INFO - Metrics service started and listening on 8008:8008
INFO - Initializing storage
INFO - Storage initialization complete
...
INFO - Slot Event *** Slot: 48641, Block: ... empty, Epoch: 1520, Finalized checkpoint: 40, Finalized root: 285a29..250e, Peers: 0
INFO - Eth1 tracker successfully caught up to chain head
INFO - Slot Event *** Slot: 48642, Block: ... empty, Epoch: 1520, Finalized checkpoint: 40, Finalized root: 285a29..250e, Peers: 0
INFO - Slot Event *** Slot: 48643, Block: ... empty, Epoch: 1520, Finalized checkpoint: 40, Finalized root: 285a29..250e, Peers: 0
INFO - Sync Event *** Current slot: 48643, Head slot: 1351, Connected peers: 1
That’s it. We have a functioning beacon node and validator. Congratulations: you are awesome!
***
NOTE: This guide is now deprecated. Please use the newer version targeting the Pyrmont testnet.
*** located here.
Step 9— Updating Teku
If the Teku client team updates the code in the Teku repository you can update the service by using the following commands.
$ cd teku
$ git pull
$ ./gradlew installDist
$ sudo systemctl stop teku
$ sudo rm -r /usr/local/teku
$ sudo cp -a ~/teku/build/install/teku/. /usr/local/teku
$ sudo systemctl start teku
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.20.0/prometheus-2.20.0.linux-amd64.tar.gz
Unpack the archive. It contains two binaries and some content files.
$ tar xvf prometheus-2.20.0.linux-amd64.tar.gz
Copy the binaries to the following locations.
$ sudo cp prometheus-2.20.0.linux-amd64/prometheus /usr/local/bin/
$ sudo cp prometheus-2.20.0.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.20.0.linux-amd64/consoles /etc/prometheus
$ sudo cp -r prometheus-2.20.0.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.20.0.linux-amd64.tar.gz prometheus-2.20.0.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-dev"
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-08-11T06:43:43.216Z caller=main.go:805 msg="Loading configuration file" filename=/etc/prometheus/prometheus.yml
level=info ts=2020-08-11T06:43:43.217Z caller=main.go:833 msg="Completed loading of configuration file" filename=/etc/prometheus/prometheus.yml
level=info ts=2020-08-11T06:43:43.219Z caller=main.go:652 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.1.3
Version table:
7.1.3 500
500 https://packages.grafana.com/oss/deb stable/main amd64 Packages
7.1.2 500
500 https://packages.grafana.com/oss/deb stable/main amd64 Packages
7.1.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
.

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


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 12523
to import Adrian Sutton’s fantastic 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 the beacon node 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
***
NOTE: This guide is now deprecated. Please use the newer version targeting the Pyrmont testnet.
*** located here.