PM2 / Monit - Migration to systemd

Ensure you are logged in as the non-root user being used to run zend and the node tracker

  • Install packages from the official guide
  • Stop tracker with pm2
  • Upgrade tracker to version 10.12.0
  • Create systemd unit for the node tracker
  • Start tracker with systemd
  • Stop zend with monit
  • Create systemd unit for zend
  • Start zend with systemd
  • Check status of zend and zentracker
  • Enable service units at boot
  • Ensure Firewall is monitored by systemd
  • Kill and remove pm2
  • Remove and purge monit
  • - Migration to certbot


Install the universe repository and packages for certbot and ensure other packages are installed and up to date from the official guide

sudo apt install software-properties-common -y

Skip adding the universe repository on Debian systems, DO NOT SKIP THE OTHER ENTRIES IN THIS STEP

sudo add-apt-repository universe -y

Be sure to copy the entire command, especially for long command strings

sudo apt-get install build-essential software-properties-common apt-transport-https lsb-release dirmngr pwgen git jq ufw curl aria2 -y
2Update the package cache
sudo apt-get update

Install curl and add the nodejs repository and update the package cache

NOTE: Skip this step for Ubuntu

Debian 9 only

sudo apt-get install curl -y
curl -sL | sudo -E bash -
sudo apt-get update
4Install npm, upgrading it to the version 10.12.0
sudo apt-get install npm -y && sudo npm install -g n && sudo n 10.12.0

Stop the node tracker

NOTE: If for some reason you have more than one tracker running in pm2, you may have to change "0" to the number that corresponds with your tracker, and stop those as well. You can get a listing of the numbers from running: pm2 list

pm2 stop 0
6Change directory to where the node tracker was cloned, this will be ~/nodetracker for the official guide and typically ~/zencash/secnodetracker for older documentation or other guides
cd ~/nodetracker

Perform the following command if the above command fails due to the directory not existing

mv ~/zencash/secnodetracker ~/nodetracker && cd ~/nodetracker
7Update git with the new repository URL and retrieve the latest source code
git checkout -- package.json
git remote set-url origin
git fetch origin
git checkout master
git pull

NOTE: If git returns an error regarding any files run the following command (replacing 'filename with the file returned in the error message) and repeat the commands above

git checkout -- filename
8Install the latest set of node modules required for the tracker
npm install

Only perform steps 9 and 10 if this has not already been ran. If you have already upgraded to nodetracker 0.3.1 this would have already been completed.

Locate your node's public IPv4 and/or IPv6 address(es) and append them to the zen.conf file as external IP address(es) connected over port 9033 (default)



NOTE: Secure Nodes only require one type of IP, Super Nodes require both

NOTE: Replace <IPv4> with the public IPv4 of your node, remove <brackets>

NOTE: Replace <IPv6> with the public IPv6 of your node in compressed notation without leading zeros, remove <brackets>

Use the following link to ensure your IPv6 address is in compressed notation:

Create environmental variables for IPv4


Append external IPv4 into zen.conf

echo "externalip=$IPV4" >> ~/.zen/zen.conf

Create environmental variables for IPv6


Append external IPv6 into zen.conf

echo "externalip=$IPV6" >> ~/.zen/zen.conf

Append port into zen.conf - SECURE AND SUPER

echo "port=9033" >> ~/.zen/zen.conf

Run node setup again to refresh the list of tracker servers and initialise the new tracker, press enter through each of the values to retain the current set

  • Enter 'secure' for the 'node category' prompt
node setup.js
11Stop zend with monit, then stop monit. Both commands are shown to stop via systemctl and sysinit (only one should be needed, but both are here for completeness)
sudo monit stop zend && sleep 8
sudo systemctl stop monit
sudo service monit stop
12Create a systemd unit file for zend, copy and paste the entire block of text
echo \
Description=Zen daemon

ExecStart=/usr/bin/zend -daemon -pid=$HOME/.zen/

[Install]" | sudo tee /lib/systemd/system/zend.service
13Test the zend unit file
sudo systemctl start zend && sleep 30

Create a systemd unit file for the Node Tracker, copy and paste the entire block of text

echo \
Description=Zen node daemon installed on ~/nodetracker/

ExecStart=$(which node) $HOME/nodetracker/app.js

[Install]" | sudo tee /lib/systemd/system/zentracker.service
15Test the tracker unit file
sudo systemctl start zentracker
16Follow the tracker output log to check everything looks OK, if all appears fine, exit with CTRL+c
sudo journalctl -fu zentracker

Example Output

zenops@node01~$ sudo journalctl -fu zentracker
-- Logs begin at Tue 2018-05-22 12:54:41 EDT. --
May 24 21:34:28 node01 node[42000]: 2018-05-25 01:34:28 GMT -- Connected to server Initializing...
May 24 21:34:28 node01 node[42000]: Secure Node t_address (not for stake)=znXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
May 24 21:34:28 node01 node[42000]: Balance for challenge transactions is 0.0247
May 24 21:34:28 node01 node[42000]: Using the following address for challenges
May 24 21:34:29 node01 node[42000]: 2018-05-25 01:34:29 GMT -- Authenticated
May 24 21:34:29 node01 node[42000]: 2018-05-25 01:34:29 GMT -- Updated server list
May 24 21:34:29 node01 node[42000]: 2018-05-25 01:34:29 GMT -- Stats: send initial stats.
May 24 21:34:29 node01 node[42000]: 2018-05-25 01:34:29 GMT -- Stats received by
May 24 21:34:29 node01 node[42000]: 2018-05-25 01:34:29 GMT -- Cert check: valid=true. Hostname
matches CN


Check the status of both zend and the tracker, both should return active (running). If the status doesn't send you back to a command prompt, exit the status details by pressing CTRL + c

sudo systemctl status zend zentracker

Example Output

zenops@node01:~$ sudo systemctl status -n 0 zend zentracker
 zend.service - Zen daemon
Loaded: loaded (/lib/systemd/system/zend.service; disabled; vendor preset: enabled)
Active: active (running) since Thu 2018-05-24 22:31:30 EDT; 34s ago
Process: 21612 ExecStart=/usr/bin/zend -daemon -pid=/home/zenops/.zen/ (code=exited, status=0/SUCCESS)
Main PID: 21615 (zend)
Tasks: 16
Memory: 810.0M
CPU: 18.963s
CGroup: /system.slice/zend.service
└─21615 /usr/bin/zend -daemon -pid=/home/zenops/.zen/

May 24 22:31:30 node01 systemd[1]: Starting Zen daemon...
May 24 22:31:30 node01 zend[21612]: Zen server starting
May 24 22:31:30 node01 systemd[1]: zend.service: PID file /home/zenops/.zen/ not readable (yet?) after start: No such file or directory
May 24 22:31:30 node01 systemd[1]: Started Zen daemon.

 zentracker.service - Zen node daemon installed on ~/nodetracker/

Loaded: loaded (/lib/systemd/system/zentracker.service; disabled; vendor preset: enabled)
Active: active (running) since Thu 2018-05-24 21:34:27 EDT; 1h 1min ago
Main PID: 19648 (node)
Tasks: 10
Memory: 38.9M
CPU: 4.110s
CGroup: /system.slice/zentracker.service
└─19648 /usr/local/bin/node /home/zenops/nodetracker/app.js

18If both work correctly, enable them at boot
sudo systemctl enable zend zentracker

Use systemctl to enable the firewall

NOTE: Many guides lacked enabling this under systemctl

If the firewall is not installed, see: Part 5 - Securing the Host

sudo ufw -f enable
sudo systemctl start ufw
sudo systemctl enable ufw
sudo systemctl status ufw

Example Output

zenops@node01:~$ sudo systemctl status ufw
[sudo] password for zenops:
ufw.service - Uncomplicated firewall
Loaded: loaded (/lib/systemd/system/ufw.service; enabled; vendor preset: enabled)
Active: active (exited) since Sat 2018-05-26 16:03:39 EDT; 23min ago
Process: 603 ExecStart=/lib/ufw/ufw-init start quiet (code=exited, status=0/SUCCESS)
Main PID: 603 (code=exited, status=0/SUCCESS)
Tasks: 0
Memory: 0B
CPU: 0
CGroup: /system.slice/ufw.service

May 26 16:03:39 node01 systemd[1]: Started Uncomplicated firewall.

20Remove pm2 from startup
sudo rm /etc/systemd/system/pm2*
sudo rm /etc/systemd/system/*

Kill and remove PM2 (if all of the above executed without error)

You may see a message about updating npm, you may ignore this

pm2 kill
sudo npm remove pm2 -g
sudo rm -r ~/.pm2

Example Output

zenops@node01:~$ pm2 kill
[PM2] Stopping PM2...
[PM2] Applying action deleteProcessId on app [all](ids: 0)
[PM2] [securenodetracker](0) ✓
[PM2] All processes have been stopped and deleted
[PM2] PM2 stopped

Example Output

zenops@node01:~$ sudo npm remove pm2 -g
removed 135 packages in 2.873s


Remove monit from startup (you may not require both commands, both are present to accommodate either systemd, or init script)

Run both commands if you're unsure of which way monit was configured

NOTE: It is expected that you will see an error if you execute the command that doesn't correspond with how monit was setup. You can safely dismiss errors from the one command of the two presented here.

sudo systemctl disable monit
sudo update-rc.d monit remove

Remove and purge monit from system and remove old repositories (if all of the above executed without error)

sudo apt-get remove monit -y
sudo apt-get purge monit -y
sudo apt-get -y autoremove
rm -rf ~/
24 - Migration to certbot

© 2020 Horizen. All rights reserved.