シェルを使ってSymbolノードを簡単構築

## メインネットでノードを構築・運用しよう！
みなさんこんにちは。あきまるです。
今回はアドカレということですが、過去に書いた簡単ノード構築記事を再度こちらに掲載しようと思います。
現在は、モバイルノード構築が流行していますが、基本は自鯖またはVPSでのノード構築かなと思っております。特にトラブった時にこのノード構築を経験しているかどうかでかなり差が出るとは思います。
また、構築するコードも全て掲載しているので、ノードトラブル時に細かく点検していくことも可能だったりします。
ということで、この記事がお役に立てることがあれば嬉しいなと思います。

ノード構築に関しては、私も2021年のローンチ時にメインネットでノードを立てましたが、結構苦労しました。
そしてかなり打ち間違えてはリセットを繰り返しました。
そんな苦い経験から、今回は簡単に構築できるよう、普段から使用しているシェルスクリプトを活用した構築・ノード更新方法を紹介します。

わかってしまえば、コピペでぱっぱといけます。だめならOSの入れ直しをして最初からやってしまう荒技だって出来ます。
参考資料として、づ～大先生の資料を最下部に添付しておきます。ご参考としてください。

## シェルはとっても便利！
シェルを使う利点は次のとおり。
 **①構築はコピペして実行するだけ** 
　構築はログインしたらシェルを作って実行するだけです。
　後は質問事項に答えていくだけ。

 **②打込み間違いを減らせる** 
　コードを打ち込み間違えてリセット！なんてこともありますよね。
　そんなリスクも極力減らすことが出来ます。

 **③更新もシェルを実行するだけ** 
　更新もシェルを使えばログインしてシェルを実行するだけ！
　sh updateって打ち込むだけで更新が出来ちゃいます。
　ノードを止めてあれやってこれやって、なんてことは不要です。

それでは、作業を始めて行きましょう！

## 全体の流れ
全体の流れは以下の通りです。
 **①VPS登録（今回はcontaboかsakuranoVPS）** 
 **②teraterm　ダウンロード** 
 **③ベース構築** 
 **④ノード構築** 

## VPSに登録しよう
お手軽にはじめるということで、VPSを利用してノードを構築していきます。
contaboについては、 **[こちらの記事](https://gemgemfx.com/contabo/ "Contabo VPSの特徴と料金・設定方法と使い方まとめ")** がわかりやすいと思いますのでご参照ください。

さくらのVPSについては、 **[こちらの記事](https://vps.sakura.ad.jp/flow/ "お申し込みの流れ")** がわかりやすいと思いますのでご参照ください。

:::note
構築する際は、LinuxのオペレーティングシステムであるUbuntuをインストールします。
今回使用するバージョンは、18.04（20.04でも可）です。
:::

## Teratermをダウンロードしよう
私は、Teratermを使用していますのでこちらで説明していきます。

 **[ダウンロードはこちら](https://web.archive.org/web/20220328182521/https://ja.osdn.net/projects/ttssh2/ "Tera Term")** 

ダウンロードが完了したら、パッケージをクリック（もしくはダブルクリック）して実行ます。
するとインストールウィザードが起動するので、ウィザードの指示に従ってインストールしてください。
導入方法の詳細は **[こちら](https://web.archive.org/web/20220525043658/https://ja.osdn.net/projects/ttssh2/howto/install "Tera Term のインストール方法")** をご覧ください。

## ノードの基礎部分を構築しよう
いよいよVPSに接続して、ノードを構築していきます。

:::note alert
その前に、TCPポートの22が解放されていて危険な状態なので、ポートを閉じたり、基礎となるプログラムがインストールされていなかったりするので、先にそちらをインストールしたりします。
:::

今回はcontabo画面での操作説明とします。

### teartermでVPSにログインする
 **①teraterm起動** 
デスクトップにあるTeratermアイコンをダブルクリックし、起動します。
![1648354583id.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1242232/2e35973c-effc-5cbf-9038-ebc67e9282e4.png)

 **②IPアドレスとTCPポートの指定** 
登録時に送られてきたメールにIPアドレスが書いてあるので入力します。
TCPポートについては、22のままでokです。

![1648354947id.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1242232/ecf694f9-76b6-f0bc-ba65-c6f077390a37.png)

 **③セキュリティ警告画面** 
何も弄らず続行を押します。
![1648354967id.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1242232/bbfc95ed-acf8-ae34-a68b-6ac743675e2b.png)

 **④ユーザーID、パスワード入力画面** 
下記の情報でログインします。
ユーザ名：root （さくらのvpsではubuntu）
パスフレーズ：VPS登録時に指定したパスワード
![1648355267id.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1242232/fd94c911-5caa-3ebf-f794-0334444b1c75.png)

 **⑤ログイン** 
このような黒い画面がでたらログイン成功です。
ちなみに、SSをとれていないのでこの写真ですが、rootでログインした時は、
root@vmi833663:~#　のような感じで表示されます。
![1648355346id.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1242232/87dfc7e1-c749-1d3e-b05a-07d03f77d084.png)

### 基礎構築シェル『b』の作成
次に、シェルというものを作成します。
シェルとは、色んなコマンドを詰め込んだファイルで、これを実行することによりたくさんのコマンドを打つ手間を省きます。
ファイル名は『b』とします。

:::note info
teratermでの文字列貼付について
　これ以降、teratermでは貼付作業が多く発生します。
　ただし、ctrl＋vでの貼付はできません。以下の方法で貼付を行ってください。
　①右クリック＞OKを押す
　②shift＋Insert＞OKを押す
　③編集＞貼付
::: 

 **①新規テキストファイルを作成する** 
viというコマンドを使用します。以下をコピペしてteratermに貼り付けし、enterを押してください。
[viの使い方はこちら](https://web.archive.org/web/20220328182521/http://psa2.kuciv.kyoto-u.ac.jp/staff/susaki/command/vi.html "viの基本操作")

```
vi b
```

teraterm画面はこんな感じ。
![1648356435id.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1242232/9b0e5a7f-0369-2f32-6f72-3853a21d31ee.png)

enterを押すと、次の画面が開きます。
![1648356612id.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1242232/c9f72be7-3c77-a8b7-567c-262c1c2ba252.png)

 **②ファイルにスクリプトを貼り付ける** 
テキストファイル画面に、次のスクリプトをコピペします。
```
#!/bin/bash

#new username
echo "??? please input new username ???"
read username

#new sshd port
echo "??? please input new sshd port ???"
read sshd
#----------
echo "continue working......."

#usernameset
adduser $username
gpasswd -a $username sudo

#sshdset
sed -i -e s/"#Port .*"/"Port 22"/ /etc/ssh/sshd_config
sed -i -e s/"Port .*"/"Port $sshd"/ /etc/ssh/sshd_config
sed -i -e s/"PermitRootLogin .*"/"PermitRootLogin no"/ /etc/ssh/sshd_config
systemctl restart sshd

#update
apt update

#ufw set
apt-get install ufw
ufw allow $sshd/tcp
ufw allow 3001
ufw allow 80

#ufw start
ufw enable
ufw status

#curl set
apt-get install curl

#docker
curl https://get.docker.com | sh
usermod -aG docker $username
systemctl start docker
systemctl enable docker
docker --version

#docker コンテナファイルの設定
echo '{"log-driver":"journald","log-opts":{"tag":"docker/{{.ImageName}}/{{.Name}}"}}' > /etc/docker/daemon.json
systemctl restart docker

#dockerログ参照は
# journalctl -f CONTAINER_NAME=api-node

#docker-compose
curl -L https://github.com/docker/compose/releases/download/1.28.5/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
docker-compose --version

systemctl restart docker

#node js
curl -sL https://deb.nodesource.com/setup_21.x | sudo -E bash -
apt-get install -y nodejs
node -v
npm -v

#npm　update
npm install -g npm@latest

#install jq
apt-get install jq

#https-portal
apt-get install https-portal

#symbol-bootstrap install
echo "Please log off After this, and use 'up' after re-login with the set sshd / username / password."
```

これをTeratermに貼り付けます。
![1648356990id.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1242232/1b4252ca-41f3-268a-a2ed-d65e62260777.png)
⬇
![1648357024id.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1242232/e2657d5a-c2e8-f5ad-20d4-837562b3de98.png)

 **③保存終了** 
:wqを直接打ち込み、enterを押すと保存終了し、元の画面に戻ります。
![1648357065id.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1242232/6a55424a-f6f0-07eb-2db8-3ec5a96e487b.png)

### シェルを実行する

先ほど作ったシェルを実行します。
次のコマンドを打ち込んでenterを押してください。

```
sh b
```

以下、質問事項については回答しつつ進めてください。
(y/n）と聞かれた場合は、yと入力してenterを押してください。
＜質問事項＞
 **①??? please input new username ???** 
今後VPSにログインする際のユーザーネームを登録します。半角英数字で入力し、enterを押してください。

 **②??? please input new sshd port ???** 
TCPポート22に変わる新しいポート番号を自分で決めて指定します。

:::note warn
Symbolのノードが使用するポートは、下記のとおり。
80/443
3000
3001　※https化する場合
7900

私は、Dynamic and/or private portsの49152～65535から選んでます。
:::

 **③新規パスワードの入力** 
新規パスワードを聞かれますので、入力してenterを押してください。

:::note alert
ここで登録したユーザーID、ポート番号、パスワードは今後ずっと使っていくものです。
むしろこれがないとVPSにログインができません。
絶対にメモって忘れないようにしてください。
また、他の人にも絶対に口外しないようにしてください。ログインされてしまいます。
:::

 **④「Full Name [ ]」～「Other [ ]」** 
すべてenterを押します。

 **⑤残り** 
たまに(Y/N）と聞かれるので、yと入力してenterを押してください。
プログラムが止まることがありますが、しばらくすると動き出します。放置しておいてください。

 **⑥完了** 
最後に『Please log off After this, and use 'up' after re-login with the set sshd / username / password.』と表示されたら基礎構築は完了です。

:::note
## 【重要】登録したユーザーとPASSでログインする
 
teratermを閉じると、設定不良なのか二度とログインできない場合があります。
その対策として、rootで立ち上げたTeratermはそのままにして、Teratermをもう一つ立ち上げます。

 **①teraterm起動** 
デスクトップにあるTeratermアイコンをダブルクリックし、起動します。
![1648354583id (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1242232/a0fe06fd-e368-613b-75b8-63a1cc3b47c2.png)

 **②IPアドレスとTCPポートの指定** 
IPアドレスは先ほどのログイン時と同じものを入力します（既に入っているとは思いますが。）
TCPポートについては、先ほど自分で指定したポート番号を入力します。
![1648359007id.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1242232/f08f8ac5-2887-4167-09d8-56836b9f23fb.png)

 **③セキュリティ警告画面** 
何も弄らず続行を押します。
![1648354967id (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1242232/959ad4f9-095d-b0e3-4ee4-b90ef8adedda.png)

 **④ユーザーID、パスワード入力画面** 
下記の情報でログインします。
ユーザ名：先ほど登録したユーザーネーム
パスフレーズ：先ほど登録したパスワード
![1648359110id.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1242232/6c177cff-d126-84c2-58b3-c5160f60a67a.png)

 **⑤ログイン成功** 
このような黒い画面がでたらログイン成功です。
![1648355346id (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1242232/a6770c85-45c1-d58d-b12c-f94ce899dc09.png)

 **⑥rootでログインしたteratermを閉じる** 
管理者権限でログインしているので、次のコマンドでログアウトします。

・管理者権限の離脱
次のコマンドを入れてenterを押してください。

```
exit
```

・ログアウト（teratermを閉じる）
次のコマンドを入れてenterを押してください。

```
logout
```

teratermが閉じます。
引き続き、新しく登録したユーザーで作業を進めていきます。


:::

## ノードを構築しよう
いよいよノード本体の構築に入ります。
手順としては先ほどの基礎部分の構築と同様です。
それでは行きましょう。

### ノード構築シェル『up』の作成

 **①新規テキストファイルを作成する** 
viというコマンドを使用します。以下をコピペしてteratermに貼り付けし、enterを押してください。

```
vi up
```

 **②ファイルにスクリプトを貼り付ける** 
テキストファイル画面に、次のスクリプトをコピペします。

```
#!/bin/bash

#input ip
echo "??? please input address or ip ??? "
read ip

#input friendlyname
echo "??? please input friendly_name ???"
read friendlyname

#input addresses
echo "??? please input beneficiaryAddress ???"
read beneficiaryAddress

## mainPrivateKeyには種銭の入ったウォレットのプライベートキーを指定
echo "??? please input mainPrivateKey ???"
read mainPrivateKey

## 委任上限設定
echo "??? please input maxUnlockedAccounts ???"
read maxUnlockedAccounts

## 最小手数料乗数設定
echo "??? please input minFeeMultiplier ??? (10-100)"
read minFeeMultiplier

## 戦略ストラテジー設定
echo "??? please input transactionSelectionStrategy ??? (oldest/)"
read transactionSelectionStrategy

## transportPrivateKey~vrfPrivateKeyは新規に生成
#echo "??? please input transportPrivateKey ???"

## transportPrivateKey~vrfPrivateKeyは新規に生成
#echo "??? please input transportPrivateKey ???"

## transportPrivateKey~vrfPrivateKeyは新規に生成
#echo "??? please input transportPrivateKey ???"

## transportPrivateKey~vrfPrivateKeyは新規に生成
#echo "??? please input transportPrivateKey ???"
#read transportPrivateKey
#echo "??? please input remotePrivateKey ???"
#read remotePrivateKey
##echo "??? please input votingPrivateKey ???"
##read votingPrivateKey
#echo "??? please input vrfPrivateKey ???"
#read vrfPrivateKey

#----------
echo "continue working......."

#install Symbol Bootstrap
sudo npm install -g symbol-bootstrap
symbol-bootstrap -v

#make workdir
mkdir -p symbol-node
cd symbol-node

#make custom config file
cat < custom.yml
nodes:
    -
        host: $ip
        friendlyName: $friendlyname
        ##voting: true
        beneficiaryAddress: $beneficiaryAddress
        mainPrivateKey: $mainPrivateKey
        ##transportPrivateKey: $transportPrivateKey
        ##remotePrivateKey: $remotePrivateKey
        ##votingPrivateKey: $votingPrivateKey
        ##vrfPrivateKey: $vrfPrivateKey
        minFeeMultiplier: $minFeeMultiplier
        transactionSelectionStrategy: $transactionSelectionStrategy
        maxUnlockedAccounts: $maxUnlockedAccounts
        certificateExpirationWarningInDays: 376
        delegatePrioritizationPolicy: Age
        maxChainBytesPerSyncAttempt: 50MB
        messageSynchronizationMaxResponseSize: 5MB
        blockDisruptorMaxMemorySize: 1000MB
httpsProxies:
    -
        excludeDockerService: false
EOF

#make config file
#新規に構築 

symbol-bootstrap config -a dual -p mainnet -c custom.yml

echo "!!! Check node status !!!"
echo "node status Ok? Ok:ENTER No:CTRL+C and restart script"
read a

echo "continue working......."

#make docker-compose.yml
symbol-bootstrap compose

#start
symbol-bootstrap run -d

symbol-bootstrap healthCheck

curl localhost:3000/chain/info|jq
curl localhost:3000/node/info|jq
curl http://localhost:3000/chain/info

#show addresses
rm -rf d_addresses.yml
symbol-bootstrap decrypt --source target/addresses.yml --destination d_addresses.yml
cat d_addresses.yml
rm -rf d_addresses.yml
```

 **③保存終了** 
:wqを直接打ち込み、enterを押すと保存終了し、元の画面に戻ります。
![1648357065id (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1242232/f239d388-2392-9873-84f0-e97ede04ebb6.png)

### シェルを実行する
先ほど作ったシェルを実行します。
次のコマンドを打ち込んでenterを押してください。

```
sh up
```

シェルが起動すると、またいくつかの質問事項が表示されるので順を追って回答してください。
ここからはノード設定を決めていきます。

 **①??? please input address or ip ???
ノードのIPアドレスかURLを聞かれます。
コピペか直接入力してenterを押します。

:::note
＜ノードURLの調べ方＞
正直IPアドレスだと格好がつかないので、以下のサイトにアクセスして、ipを打ち込んでください。URLが出力されます。
https://www.cman.jp/network/support/ip.html
:::

 **②??? please input friendly_name ???** 
ノードに名前をつけてあげてください。
入力してenterを押します。

 **③??? please input beneficiaryAddress ???** 
ノード報酬が入るウォレットアドレスを入力してください。
メインネットのウォレットを準備されていない方は準備お願いします。
ハイフンは除外します。

 **④??? please input mainPrivateKey ???** 
ノード報酬が入るウォレットアドレスのプライベートキーを入力してください。

 **⑤??? please input maxUnlockedAccounts ???** 
委任者の上限を設定します。

 **⑥??? please input minFeeMultiplier ??? (10-100)** 
最小手数料乗数を設定します。
安い手数料にしたい場合は、10にしましょう。

 **⑦??? please input transactionSelectionStrategy ??? (oldest/)** 
トランザクション処理の方法。oldestは古いトランザクションから順番に処理していくというもの。
他にはmaxとminとありますが、ごめんなさい。設定値名忘れたのでまた調べておきます。とりあえずoldest。

 **⑧のこり** 
後はパスワードが何度も求められますので、入力してenterを押してください。
プログラムが止まることがありますが、しばらくすると動き出します。放置しておいてください。

以上です。

https化は勝手にしてくれるように組み込んでおきました。
委任順もめんどくさいのでage（先着順）設定です。
づ～さんの言っていたおっきなファイルサイズのトランザクションを乗り越えるための設定も適用済みです。

## ノードの動作確認をしよう
ノードを構築したら、ちゃんと動いているかブロック高を確認したり、ヘルスチェックをしたりします。
こちらは、いくつかのヘルスチェック項目を詰め込んだシェルを作成し、実行させるものです。
ノードはちゃんとうごいているかな？という時にはこちらを実行してください。

### 動作確認シェル『check』の作成

動作確認用シェル『check』を作っていきます。

 **①新規テキストファイルを作成する** 
viというコマンドを使用します。以下をコピペしてteratermに貼り付けし、enterを押してください。

```
vi check
```

enterを押すと、次の画面が開きます。
![1648356612id (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1242232/85330788-dbcb-3af3-9ee4-669122805b9a.png)

 **②ファイルにスクリプトを貼り付ける** 
テキストファイル画面に、次のスクリプトをコピペします。

貼付用スクリプト
```
#!/bin/bash

#ディレクトリ移動
cd symbol-node

#Symbol-bootstrapバージョン確認
symbol-bootstrap -v

#サーバー情報確認
curl http://localhost:3000/node/server

#ノードブロック高確認
curl http://localhost:3000/chain/info

#APIノード疎通をローカルで確認
curl http://localhost:3000/node/info|jq

#アカウント情報確認
curl localhost:3000/node/unlockedaccount|jq

#ハーベスト情報表示
cat target/nodes/node/server-config/resources/config-harvesting.properties

#ヘルスチェック実行
symbol-bootstrap healthCheck

cd

```

 **③保存終了** 
:wqを直接打ち込み、enterを押すと保存終了し、元の画面に戻ります。
![1648357065id (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1242232/36ed74bd-efb7-1283-46e1-f08363bad46a.png)

### シェルを実行する

先ほど作ったシェルを実行します。
次のコマンドを打ち込んでenterを押してください。

```
sh check
```

実行すると以下のことが確認できます。
 **①bootstrapのバージョン情報** 
 **②サーバ情報確認** 
 **③ブロック高確認** 
 **④APIノード疎通をローカルで確認** 
 **⑤アカウント情報確認** 
 **⑥ハーベスト情報確認** 
 **⑦ヘルスチェック実行** 

最後のヘルスチェックで、 **Network is runnning!!** と表示されていればノードはとりあえず動いています。
後は、ブロック高などがちゃんと実際のブロック高に追いついているか確認してください。

## ノード更新をしよう！
ノードを構築したら、ちゃんと動いているかブロック高を確認したり、ヘルスチェックをしたりします。
こちらは、いくつかのヘルスチェック項目を詰め込んだシェルを作成し、実行させるものです。
ノードはちゃんとうごいているかな？という時にはこちらを実行してください。

### ノード更新用シェル『update』の作成
ノード更新用シェル『update』を作っていきます。

 **①新規テキストファイルを作成する** 
viというコマンドを使用します。以下をコピペしてteratermに貼り付けし、enterを押してください。

```
vi update
```

enterを押すと、次の画面が開きます。
![1648356612id (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1242232/40b3299c-25d7-b460-19f6-192fab7b9faf.png)

 **②ファイルにスクリプトを貼り付ける** 
テキストファイル画面に、次のスクリプトをコピペします。

貼付用スクリプト
```
#!/bin/bash
cd symbol-node
symbol-bootstrap stop #ノードを止める

sudo rm -rf target.bak1　#古いバックアップファイルを削除
sudo cp -r target target.bak1　#現在のターゲットフォルダ内をバックアップ

sudo npm install -g symbol-bootstrap


symbol-bootstrap config -a dual -p mainnet -c custom.yml --upgrade

#ノード証明書情報更新
symbol-bootstrap renewCertificates --force


#docker-compose.yml削除
cd target/docker
sudo rm -rf docker-compose.yml

cd
cd symbol-node

#make docker-compose.yml
symbol-bootstrap compose


#start
symbol-bootstrap run -d

symbol-bootstrap healthCheck
curl localhost:3000/chain/info|jq
curl localhost:3000/node/info|jq
curl localhost:3000/node/unlockedaccount|jq

rm -rf d_addresses.yml
symbol-bootstrap decrypt --source target/addresses.yml --destination d_addresses.yml
cat d_addresses.yml
rm -rf d_addresses.yml

symbol-bootstrap -v

cat target/nodes/node/server-config/resources/config-harvesting.properties
```

### シェルを実行する
先ほど作ったシェルを実行します。
次のコマンドを打ち込んでenterを押してください。
```
sh update
```

:::note
私の場合、更新時に何故かdockerが不具合起こすので、めんどくさいから一度消して再構築しています。
:::

:::note alert
現在、ノードを更新しても　『②サーバ情報確認』をすると、bootstrapのバージョンが元のままになっていることがあります。
　その場合、もう一度アップデートを実行すると治りますので、sh updateを実行してみてください。
:::

## 参考書
づ～さん　　　
["b" Symbol bootstrap 動作環境 自動構築 shellscript（ﾍﾞｰｽ構築）](https://web.archive.org/web/20220328182521/https://qiita.com/dusanjp/items/505bf4f3598c7dd90461)

[Symbol node 起ち上げ（ふりーはんど版）【"b" にも対応してます】](https://web.archive.org/web/20220328182521/https://qiita.com/dusanjp/items/7410700885deea0f5b0b)