IOTA Full Node Copy-Paste
Installation Guide

There are many reasons to run your own IOTA full node. In general, each full node contributes to the scaling of the tangle and offers the possibility to connect your wallet to it.

Responsive image

This tutorial provides a few copy-paste Linux console commands to run a complete, stable node within a few minutes. All you need is some time, patience, a rental server and basic console knowledge.

Discord is the primary communication platform for the IOTA community. If you have not already joined, use this link. In the channel #fullnodes you can get support in English and in the channel #fullnodes-ger in German. Make sure to follow the instructions precisely. In case you already have a node installation, which does not run properly, you should reinstall the server before proceeding.

1. Server

For a simple node that should not spam, a VPS (Virtual Private Server) with 2 cores and 4GB RAM (8GB / 4 cores are of course better) is currently sufficient. An SSD hard disk is highly recommended but not mandatory. The disk space does not have to be larger than 30GB and the data transfer traffic of almost all providers is so high that we can ignore it.

I do not recommend running a node on a desktop computer. Technically, this works, but you will hardly find reliable neighbors because most of them are looking for nodes that run 7 days a week without interruption.

There are many hosters and in principle you have free choice. However, it is known that some providers have problems with the udp protocol (such as Scaleway) - at least in the way IRI uses it. This is an important point, because many neighbors want to use only UDP.

On the right hand side, you can see a small list of EU / German host providers who already have nodes running on their machines. The offers are quite similar, but Hetzner stands out with its server exchange. There you can rent high performance physical servers (instead of virtual servers) relatively cheap.

2. Image / Provisioning

For the sake of simplicity, we will focus on Ubuntu. For your server consider the following points:

  • minimal Ubuntu server installation 16.04. or higher
  • SSH access with a key or password
    if you don't know what to do with keys, choose a password (default)
  • A public IP address

Ignore or disable other options such as firewall, plesk, support, etc. as it is unnecessary and can cause problems.

Settings

We need some parameters for the configs in the next steps.

We limit the use of java memory and reserve some memory for Ubuntu (and the IRI-DB). Enter the max. ammount of RAM (megabyte) for the IRI - we keep it simple: 75% of the installed system RAM should be fine. If your server has 4GB installed RAM you would enter 3000.

Server IP Address

Enter the public IP address of your server

Neighbors

Ideally, you should have 3 - 5 neighbors. You must always expect your neighbors to crash or simply disappear - just like in real life. Too many neighbors could get your node into trouble with high network load. Both neighbors must add each other using the same protocol: udp or tcp.

Find new neighbors

Go to the Discord channel #nodesharing and ask for new neighbors. Describe a little bit your server, because many want to have exclusively powerful neighbors: who wants to be in my neighborhood? VPS 8GB, 4 cores, SSD, 24/7 hosted in a data center. A second possibility is the helloiota forum. Interested neighbors will write you a private message (PM/DM). You have to agree on a protocol first and then exchange the node-data: udp://your-public-ip-address:14600 or tcp://your-public-ip-address:15600

3. Ubuntu-Installation

As soon as the server is up and running, log in with SSH. I can't give Windows users any details, but I recommend the PUTTY client.

Since you have to change some commands and config files in a text editor under Windows, I recommend using Notepad++. Ordinary editors can insert invisible special characters.

User / sudo

For installations that use ubuntu as a user, we have to execute many commands with sudo. If your user is root, you don't need to do that. As sudo works for both types of users, all examples will include it.

First log-in on the server

Depending on your host provider you have to log in either with ubuntu or root. At the first login you will probably get a hint about known hosts. You can simply confirm this with yes.

ssh root@< click here to set your server ip address >

Update

We want to update the OS first. A kernel update requires a reboot - follow the instructions in the terminal.
Make a reboot if required by entering sudo reboot.

sudo apt update -qqy --fix-missing && sudo apt-get upgrade -y && sudo apt-get clean -y && sudo apt-get autoremove -y --purge

Packages

We need some packages, such as Java. Oracle has proven to be the better choice because many people have problems with OpenJDK. We also use the older version 8, because with 9 there are known problems as well. Oracle also obviously consumes less resources. Unfortunately Oracle requires a license confirmation from you, so you will have to confirm the pop-up window which appears during the installation. The jq package makes the JSON output easier to read.

sudo apt install software-properties-common -y && sudo add-apt-repository ppa:webupd8team/java -y && sudo apt update && sudo apt install oracle-java8-installer curl wget jq git -y && sudo apt install oracle-java8-set-default -y

Settings

We want to tell our OS which java we want to use by default

sudo sh -c 'echo JAVA_HOME="/usr/lib/jvm/java-8-oracle" >> /etc/environment' && source /etc/environment

IOTA user

For security reasons we do not start our node with the root- (admin-) user, but create an user iota without log-in rights.

sudo useradd -s /usr/sbin/nologin -m iota

Directories

We create the directory structure for the node (IRI) application

sudo -u iota mkdir -p /home/iota/node /home/iota/node/ixi /home/iota/node/mainnetdb

IRI Installation

We download the official and current version (1.4.2.2) from github into the node-directory

sudo -u iota wget -O /home/iota/node/iri-1.4.2.2.jar https://github.com/iotaledger/iri/releases/download/v1.4.2.2/iri-1.4.2.2.jar

4. Systemd Service

Of course we want our node to start automatically after a reboot or crash and create a systemd service for it.

Just copy and paste everything into the console. Make sure you have set the Xmx parameter

cat << "EOF" | sudo tee /lib/systemd/system/iota.service
[Unit]
Description=IOTA (IRI) full node
After=network.target

[Service]
WorkingDirectory=/home/iota/node
User=iota
PrivateDevices=yes
ProtectSystem=full
Type=simple
ExecReload=/bin/kill -HUP $MAINPID
KillMode=mixed
KillSignal=SIGTERM
TimeoutStopSec=60
ExecStart=/usr/bin/java -Xmx< click here to set Xmx >m -Djava.net.preferIPv4Stack=true -jar iri-1.4.2.2.jar -c iota.ini
SyslogIdentifier=IRI
Restart=on-failure
RestartSec=30

[Install]
WantedBy=multi-user.target
Alias=iota.service

EOF

We are now enabling the new service. Every time you change something in this file you need to run sudo systemctl daemon-reload.

sudo systemctl daemon-reload && sudo systemctl enable iota.service

Since we have created an alias for the service, we will be able to work with it in the future as follows
(please do not start the iota/IRI server at this point): sudo service iota start|stop|restart|status

5. IRI (IOTA Reference Implementation)

We need 3 ports that are freely configurable, but recently a scheme has been established that we want to keep. PORT is used to communicate with the API of the IRI. For example, a wallet would use this port. UDP_RECEIVER_PORT and TCP_RECEIVER_PORT are used to communicate with our neighbors NEIGHBORS. There is no reason to change these ports here.

IRI config

It makes no sense to start the node without at least one neighbor. Click here to add neighbors to this config

cat << "EOF" | sudo -u iota tee /home/iota/node/iota.ini
[IRI]
PORT = 14265
UDP_RECEIVER_PORT = 14600
TCP_RECEIVER_PORT = 15600
API_HOST = 0.0.0.0
IXI_DIR = ixi
HEADLESS = true
DEBUG = false
TESTNET = false
DB_PATH = mainnetdb
RESCAN_DB = false

REMOTE_LIMIT_API = "removeNeighbors, addNeighbors, interruptAttachingToTangle, attachToTangle, getNeighbors, setApiRateLimit"

NEIGHBORS = < click here to add neighbors >
EOF

6. Database

Since a synchronization can take several days depending on the performance of your system and of your neighbors we use an already synchronized database, created every hour. This means that you only have to synchronize the milestones of the last hour which should be much faster - if you have good neighbors. You don't have to do a rescan because the database is a complete copy.

If you prefer to synchronize from the beginning for whatever reason, it's absolutely OK. You only have to wait longer under certain circumstances. In this case, you can now go directly to step 7. Start (below).

Install the Database

cd /tmp/ && curl -LO http://db.iota.partners/IOTA.partners-mainnetdb.tar.gz && sudo -u iota tar xzfv /tmp/IOTA.partners-mainnetdb.tar.gz -C /home/iota/node/mainnetdb && rm /tmp/IOTA.partners-mainnetdb.tar.gz

7. Start

Start the node as soon as you have at least one neighbor.

Start Node (the first time)

restart does the same thing if the node is not running

sudo service iota start

IRI Auto Update

We check every 15 minutes if there is a newer version of IRI and install it automatically.

echo '*/15 * * * * root bash -c "bash <(curl -s https://gist.githubusercontent.com/zoran/48482038deda9ce5898c00f78d42f801/raw)"' | sudo tee /etc/cron.d/iri_updater > /dev/null

Monitor log after startup

journalctl -u iota -f

IRI API - Synchronisation

Your node is synchronized if these two numbers are identical latestMilestoneIndex == latestSolidSubtangleMilestoneIndex.
See 9. Operation (IRI API - SHOW IRI STATUS). You can find the current milestone in the Discord channel #botbox.
After each restart your latestSolidSubtangleMilestoneIndex will start with 999999999... and should display the value from #botbox after a few minutes and then automatically increase. It's okay if you're behind the milestone from the #botbox by a few digits.


With journalctl -u iota -f you can also see in the logfile whether the synchronization works: [Solid Milestone Tracker] INFO com.iota.iri.Milestone - Latest SOLID SUBTANGLE milestone has changed from #123456 to #123457.

8. Managing neighbors (without node restart)

When the node is running, you can add (or remove) new neighbors on-the-fly with API calls. However, you have to also add (or remove) the new neighbors in the /home/iota/node/iota.ini file. Otherwise, the changes you made via the API calls are lost with the next restart. For this, just follow the instructions about editing the iota.ini file from earlier. It is not necessary to restart the node, when adding or removing neighbors with API calls!

Add (one or more at the same time)

Separate neighbors by comma.

curl -H 'X-IOTA-API-VERSION: 1.4' -d '{"command":"addNeighbors", "uris":[
  "tcp://ip-of-the-new-neighbor:12345", "udp://ip-of-the-new-neighbor:54321"
]}' http://localhost:14265

Remove (one or more at the same time)

Similarly to adding neighbors.

curl -H 'X-IOTA-API-VERSION: 1.4' -d '{"command":"removeNeighbors", "uris":[
  "tcp://ip-of-the-new-neighbor:12345", "udp://ip-of-the-new-neighbor:54321"
]}' http://localhost:14265

9. Operation

Ideally your node is running and now you want to know if everything is working. Usually you can
exit programs on the console with q, Esc or strg+c.

Monitoring

Browse the logfile

journalctl -u iota

Display logfile output live

journalctl -u iota -f

IRI API - Show all neighbors

A reliable indicator of a functioning neighborhood is the value numberOfNewTransactions. After a restart it can takes 1-2 minutes until something happens. Functioning means a value > 0.

curl http://localhost:14265 -X POST -H 'Content-Type: application/json' -H 'X-IOTA-API-Version: 1.4' -d '{"command": "getNeighbors"}' | jq

IRI API - Show IRI Status

curl http://localhost:14265 -X POST -H 'Content-Type: application/json' -H 'X-IOTA-API-Version: 1.4' -d '{"command": "getNodeInfo"}' | jq

IRI API - Synchronisation

Your node is synchronized if these two numbers are identical (see show IRI status from above) latestMilestoneIndex == latestSolidSubtangleMilestoneIndex. You can find the current milestone in the Discord channel #botbox. After each restart, your latestSolidSubtangleMilestone will display 999999999... and should display the value from #botbox (after a few minutes) and then automatically increase.


With journalctl -u iota -f you can also see in the logfile whether the synchronization works: [Solid Milestone Tracker] INFO com.iota.iri.Milestone - Latest SOLID SUBTANGLE milestone has changed from #123456 to #123457.

10. Good Neighborhood

You will soon realize the importance of a reliable neighborhood. So make a note in your iota.ini file from whom you got which node. This way you know whom to contact in case of problems.

# Neighborhood
# Active
# discord-user-name-1 | 26.11.2017 | ip-address | udp://address:14624
# discord-user-name-2 | 27.11.2017 | ip-address | tcp://address:15555
# ...

# Unreliable
# discord-user-name-3 | 27.11.2017 | ip-address | udp://address:17134 -> is offline every night

# Lost
# discord-user-name-3 | 27.11.2017 | ip-address | tcp://address:1074 -> offline since 30.11.2017 - does not respond in Discord

If you know that you have to take your server offline for a long time or even quit, tell your neighbors. If you notice that a neighbor has problems (numberOfNewTransactions is 0 or hasn't been growing for several hours), ask him what's going on before you remove him from your config iota.ini. Treat your neighbors the way you want them to treat you.


Remove bad neighbors, i.e. those who are offline and do not respond in the Discord, quickly. These harm you and other neighbors. If you have neighbors who produce NumberOfInvalidTransactions, you should remove them very quickly - those are the most harmful.

11. Wallet

By running a full node you are making an important contribution to stabilizing and accelerating the entire IOTA/Tangle network! As a reward, you will be able to use your own node for your wallet in the future and not have to search for a working node each time.

Connect the Wallet to your node

To do this, select tools -> Edit Node Configuration in the Wallet and choose Custom (at the bottom of the list) as Host. The other values remain unchanged and have nothing to do with your node.


At the bottom left you see 2 numbers (latestMilestoneIndex and latestSolidSubtangleMilestoneIndex) which must be identical. Only if these numbers are identical and correspond to the number from the channel #botbox, you can use your wallet.

My balance is 0

If your wallet displays your full balance with another node, but not with your own, you only have to generate (and attach) addresses in the wallet until the balance appears.

12. Prometheus

We use Prometheus (with the IOTA exporter) for long-term statistics and monitoring.

Nodejs

We first install nodejs which is required by the IOTA exporter

cd /tmp && curl -sL https://deb.nodesource.com/setup_9.x | sudo -E bash - && sudo apt update && sudo apt install -y nodejs

Prometheus

Add a Prometheus user

sudo useradd -s /usr/sbin/nologin -m prometheus && sudo -u prometheus mkdir -p /home/prometheus/prometheus2

Install Prometheus

cd /tmp && curl -LO https://github.com/prometheus/prometheus/releases/download/v2.0.0/prometheus-2.0.0.linux-amd64.tar.gz && sudo -u prometheus tar xzfv /tmp/prometheus-2.0.0.linux-amd64.tar.gz -C /home/prometheus/prometheus2 --strip-components 1 && rm /tmp/prometheus-2.0.0.linux-amd64.tar.gz

Configuration file

cat << "EOF" | sudo -u prometheus tee /home/prometheus/prometheus2/prometheus.yml
global:
  scrape_interval: 15s
  evaluation_interval: 15s

scrape_configs:
  - job_name: 'prometheus'
    scrape_interval: 5s
    static_configs:
      - targets:
        - 'localhost:9090'

  - job_name: 'node_exporter'
    scrape_interval: 5s
    static_configs:
      - targets:
        - 'localhost:9100'
    params:
      collect[]:
        - cpu
        - meminfo
        - diskstats
        - netdev
        - netstat

  - job_name: 'iota_exporter'
    scrape_interval: 5s
    static_configs:
      - targets:
        - 'localhost:9311'
EOF

Prometheus Service

cat << "EOF" | sudo tee /lib/systemd/system/prometheus.service
[Unit]
Description=Prometheus
Wants=network-online.target
After=network.target

[Service]
Type=simple
WorkingDirectory=/home/prometheus/prometheus2
User=prometheus
PrivateDevices=yes
ProtectSystem=full
ExecReload=/bin/kill -HUP $MAINPID
KillMode=mixed
KillSignal=SIGTERM
TimeoutStopSec=60
ExecStart=/home/prometheus/prometheus2/prometheus --web.listen-address="localhost:9090" --config.file=/home/prometheus/prometheus2/prometheus.yml
Restart=on-failure
RestartSec=30

[Install]
WantedBy=multi-user.target
Alias=prometheus.service

EOF

Enable and start the service

sudo systemctl daemon-reload && sudo systemctl enable prometheus.service && sudo service prometheus start

Prometheus node exporter

Install the node exporter

sudo -u prometheus mkdir -p /home/prometheus/node_exporter && cd /tmp && curl -LO https://github.com/prometheus/node_exporter/releases/download/v0.15.2/node_exporter-0.15.2.linux-amd64.tar.gz && sudo -u prometheus tar xzfv /tmp/node_exporter-0.15.2.linux-amd64.tar.gz -C /home/prometheus/node_exporter --strip-components 1 && rm /tmp/node_exporter-0.15.2.linux-amd64.tar.gz

Install the service for the node exporter

cat << "EOF" | sudo tee /lib/systemd/system/node_exporter.service
[Unit]
Description=Prometheus Node Exporter
Wants=network-online.target
After=network.target

[Service]
Type=simple
WorkingDirectory=/home/prometheus/node_exporter
User=prometheus
PrivateDevices=yes
ProtectSystem=full
ExecReload=/bin/kill -HUP $MAINPID
KillMode=mixed
KillSignal=SIGTERM
TimeoutStopSec=60
ExecStart=/home/prometheus/node_exporter/node_exporter --web.listen-address='localhost:9100'
Restart=on-failure
RestartSec=30

[Install]
WantedBy=multi-user.target
Alias=node_exporter.service

EOF

Enable and start the node exporter service

sudo systemctl daemon-reload && sudo systemctl enable node_exporter.service && sudo service node_exporter start

IOTA exporter

Install git, clone and install the IOTA exporter from GitHub

cd /tmp && sudo apt install git -y && sudo -s -H -u prometheus git clone https://github.com/crholliday/iota-prom-exporter.git /home/prometheus/iota-prom-exporter && cd /home/prometheus/iota-prom-exporter && sudo -s -H -u prometheus npm install

IOTA exporter config

cat << "EOF" | sudo -u prometheus tee /home/prometheus/iota-prom-exporter/config.js
let path = require('path')
global.rootPath = path.normalize(path.join(__dirname, '..', '..'))

module.exports = {
    // url and port of your IRI node
    iota_node_url: 'http://localhost:14265',

    // keep this
    stresstest_table_url: 'http://analytics.iotaledger.net/stresstest.table',

    // address and port where the exporter will be bound
    bind_address: '127.0.0.1',
    bind_port: 9311
}

EOF

IOTA exporter Service

cat << "EOF" | sudo tee /lib/systemd/system/iota_exporter.service
[Unit]
Description=Prometheus IOTA Exporter
Wants=network-online.target
After=network.target

[Service]
Type=simple
WorkingDirectory=/home/prometheus/iota-prom-exporter
User=prometheus
PrivateDevices=yes
ProtectSystem=full
ExecReload=/bin/kill -HUP $MAINPID
KillMode=mixed
KillSignal=SIGTERM
TimeoutStopSec=60
ExecStart=/usr/bin/node /home/prometheus/iota-prom-exporter/app.js
Restart=on-failure
RestartSec=30

[Install]
WantedBy=multi-user.target
Alias=iota_exporter.service

EOF

Enable and start the IOTA exporter service

sudo systemctl daemon-reload && sudo systemctl enable iota_exporter.service && sudo service iota_exporter start

13. Grafana

Grafana is the leading graph and dashboard builder for visualizing time series infrastructure and application metrics
Please remember to set the initial Grafana password (step #2) before continuing

Install dependencies, download and install Grafana.

sudo apt install -y wget libfontconfig && cd /tmp && curl -LO https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana_4.6.3_amd64.deb && sudo dpkg -i grafana_4.6.3_amd64.deb && sudo rm grafana_4.6.3_amd64.deb

Grafana config

cat << "EOF" | sudo tee /etc/grafana/grafana.ini
app_mode = production
instance_name = ${HOSTNAME}

[server]
http_port = 3000
domain = localhost
root_url = http://localhost:3000
enable_gzip = true

[security]
# default admin user, created on startup
admin_user = admin
admin_password = < password not set! click here >
login_remember_days = 365
cookie_username = grafana_user
cookie_remember_name = grafana_remember

[users]
allow_sign_up = false
allow_org_create = false

[auth.anonymous]
enabled = false

EOF

Enablethe Grafana service

sudo systemctl daemon-reload && sudo systemctl enable grafana-server

Start the Grafana server

sudo service grafana-server start && sleep 6

Install the default datasource

curl -H "Content-Type: application/json" -X POST -u admin:< password not set! click here > -d '{"name":"Prometheus","type":"prometheus","typeLogoUrl":"","access":"proxy","url":"http://localhost:9090","basicAuth":false,"isDefault":true}' http://localhost:3000/api/datasources

Download the dashboards

cd /etc/grafana && sudo wget -O /etc/grafana/prometheus-dashboard-prometheus.json https://gist.githubusercontent.com/zoran/d0f21e67dc81eb424d4c22a234641788/raw
cd /etc/grafana && sudo wget -O /etc/grafana/prometheus-dashboard-node.json https://gist.githubusercontent.com/zoran/7fc75d8f9f45d6d6fbeac57200841e1a/raw
cd /etc/grafana && sudo wget -O /etc/grafana/prometheus-dashboard-iota.json https://gist.githubusercontent.com/zoran/085eae1b82bb83aa0cd6cabed3a2b9f0/raw

Install the dashboards

curl -H "Content-Type: application/json" -X POST -u admin:< password not set! click here > -d @/etc/grafana/prometheus-dashboard-prometheus.json http://localhost:3000/api/dashboards/db
curl -H "Content-Type: application/json" -X POST -u admin:< password not set! click here > -d @/etc/grafana/prometheus-dashboard-node.json http://localhost:3000/api/dashboards/db
curl -H "Content-Type: application/json" -X POST -u admin:< password not set! click here > -d @/etc/grafana/prometheus-dashboard-iota.json http://localhost:3000/api/dashboards/db

Grafana Dashboard

Now visit your shiny new dashbobard.

User: admin, Password: < password not set! click here >

http://< click here to set your server ip address >:3000/dashboard/db/iota

Donations

My IOTA donation address
NETJOOFVIJKHMUQHAMLBWMYGTOCWXNVLKTZ9FGYZAOVHRNPEPGTCJYGWB9MJDHQZKCXVXMLDHCPVHKOPWTEXDEVMD9

Contact

You can find me in the IOTA Discord (Zoran) or you can send me an e-mail

Copyright © IOTA.partners 2018