[Symbol]ラズパイでノードを運用してみよう(Rest構築編)

Raspberry PiでSymbolのdualノードを構築、ハーベスト設定、HTTPS化、運用まで。
本記事ではAPIノードとして必要なモジュールの構築、HTTPS化までを扱います。
Client構築編：Clientインストールまで
Client設定編：ハーベスト設定まで
Rest構築編：HTTPS化まで <- 今ここ
メンテナンス編：HA構成、アップグレードetc

(追記)4/11 Catapult-Restの起動方法を修正しました。

構築イメージ、ドキュメント
===
各モジュールの関係はこのような感じです。

https://docs.symbol.dev/ja/guides/network/running-a-symbol-node-manually.html#build-an-api-node

バージョン情報
===
Catapult-Rest: 2.4.0
MongoDB: 4.4.8
※今はまだ、バージョンを重ねるごとに構築手順やディレクトリ構造が変わっています。このバージョンでない場合、手順が異なる可能性が高いのでご了承ください。
※MongoDBは4.4.8で動作を確認しました。現在4.4.13まであるようです。メジャーバージョンの異なる5.x.xはうまく動作しなかった記憶。。

MongoDBのインストール
===
debパッケージからやったり、最新バージョンを入れる方法はいろいろあるのですが、上のSymbolドキュメントに書いてある「パッケージマネージャを使うことは非推奨」という言葉を深読みして.tgzからしました。
```bash
apt install -y libcurl4 openssl liblzma5
```
mongdbをダウンロードしインストールします。とても簡単です。
```bash
wget https://fastdl.mongodb.org/linux/mongodb-linux-aarch64-ubuntu2004-4.4.8.tgz
tar -zxvf mongodb-linux-aarch64-ubuntu2004-4.4.8.tgz
sudo cp <mongodb-install-directory>/bin/* /usr/local/bin/
```
終わりです。vesion確認のコマンドを叩いて動作することを確認します。

```bash
mongo --version
```

DB初期化とbroker起動確認
===
dbの格納先を作成します。Client設定編で試しに動作させたcatapult.serverによって作られたdataディレクトリはいったん削除して再作成します。
```bash
cd /<install-dir>/symbol/client/catapult/_build/
rm -rf data
mkdir dbfiles
mddir data
```
MongoDBを裏で走らせておきます。
```bash
mongod --dbpath=dbfiles --wiredTigerCacheSizeGB 2 --bind_ip 127.0.0.1 --logpath /var/log/mongodb/mongod.log --fork
```
初期化スクリプトを実行します。
```bash
cd /<install-dir>/symbol/client/catapult/scripts/mongo/
mongo 127.0.0.1/catapult < ./mongoDbPrepare.js
```
catapult.brokerを実行してみます。catapult.serverは裏で走らせておきます。
```bash
cd /<install-dir>/symbol/client/catapult/_build/bin
nohup ./catapult.server > /dev/null 2>&1 &
./catapult.broker ..
```
エラーで異常終了せず、走りつづけていれば成功です。
確認できたのでctrl-cで停止、catapult.serverとmongodbプロセスもkillします。

Catapult-Restの構築
===
最新のnpm、node.js、yarnをインストールします。
githubのドキュメントはおそらくbootstrapで動作させることが背景になってると思いますが、Node.jsとyarnがあれば動作します。

https://github.com/symbol/symbol/blob/dev/client/rest/README.md

bootstrapでの構築でもここらへんはインストールすると思うので割愛します。このサイトを参考にさせていただきました。最新版じゃないと動作しないのでnpmからインストールします。

https://www.softel.co.jp/blogs/tech/archives/6487

Catapult-Restは /\<install-dir\>/symbol/catapult/client/rest/にあります。しかし、このCatapult-Restは特にgithubからバージョンのタグがきられたものを持ってこないと動作しない経験が多いです。なので丸っと入れ替えます。
```bash
cd /<install-dir>/symbol/catapult/client/
rm -rf rest
git clone https://github.com/symbol/symbol.git -b rest/v2.4.0
cp -r ./symbol/client/rest ./
rm -rf symbol
```
依存関係をインストールするスクリプトを実行します。
```bash
cd /<install-dir>/symbol/catapult/client/rest/
./yarn_setup.sh
```
時間かかるのでコーヒータイム。
設定ファイルは/\<install-dir\>/symbol/catapult/client/rest/rest/resouces/rest.jsonです。一つ一つパラメータを独自にカスタマイズしてもいいと思いますが、前回ノートPC上に建てたbootstrapからパラメータ最適化されたものをコピーして持ってきます。bootstrap上では/\<install-dir\>/symbol-bootstrap/target/gateways/rest-gateway/にあります。
パスなど編集する必要があるパラメータを載せます。"deployment"はbootstrapに関する情報なのでお好きにそれらしいような値を入れます。"apiNode"に入っている各パスは一例です。
```json
...
  "port": 3000,
  "protocol": "HTTP",
  "sslKeyPath": "",
  "sslCertificatePath": "",
...
 "apiNode": {
    "host": "127.0.0.1",
    "port": 7900,
    "timeout": 1000,
    "tlsClientCertificatePath": "/<install-dir>/symbol/client/catapult/_build/cert/node.crt.pem",
    "tlsClientKeyPath": "/<install-dir>/symbol/client/catapult/_build/cert/node.key.pem",
    "tlsCaCertificatePath": "/<install-dir>/symbol/client/catapult/_build/cert/ca.cert.pem",
    "networkPropertyFilePath": "/<install-dir>/symbol/client/catapult/_build/resources/config-network.properties",
    "nodePropertyFilePath": "/<install-dir>/symbol/client/catapult/_build/resources/config-node.properties"
  },
...
  "deployment": {
    "deploymentTool": "manual",
    "deploymentToolVersion": "manual",
    "lastUpdatedDate": "yyyy-mm-dd"
  }
}
```
~~コード内(/.../rest/src/index.js)にあるrest.jsonへのパスとyarn startが実行されるディレクトリが合わず、「rest.jsonがみつからない」と実行時にエラーがでます。resoucesディレクトリを
/\<install-dir\>/symbol/client/catapult/rest/配下にコピーするかコードを相対パスから絶対パスに修正するかしておきます。修正箇所は66行目付近にあります。~~
(追記)4/11 下のコードに思いっきり引数で取ってきて、空の場合はこのパス！とコーディングされてますね。。。(謝罪します。)
コードは修正せず、起動はyarn start ./resouces/rest.jsonでしましょう。他、起動確認のところでyarn start -> yarn start ./resouces/rest.jsonに訂正しました。

```javascript:/[install-dir]/symbol/client/catapult/rest/rest/src/index.js
...
const loadConfig = () => {
        let configFiles = process.argv.slice(2);
        if (0 === configFiles.length)
                configFiles = ['/<install-dir>/symbol/client/rest/rest/resources/rest.json'];
...
```
dualノードの起動確認
===
catapult.serverとcatapult.brokerは一度試しに動作確認しました。catapult.serverとcatapult.brokerは息を合わせて連携して動作しています。初回起動以降は起動前に毎回catapult.recoveryを実行するのがいいです。recoveryをしないとたまにbrokerの起動に失敗します。
```bash:/[install-dir]/symbol/catapult/client/_build/bin
./catapult.recovery
```
dualノードを起動します。catapult.server、catapult.serverは裏で走らせます。ずっと走らせる場合はnohupで。catapult.serverは出力が多いので/dev/nullに吐き出しときます。別でbin/log/に出力内容はすべて記録されます。
```bash
cd /<install-dir>/symbol/client/catapult/_build/
mongod --dbpath=dbfiles --wiredTigerCacheSizeGB 2 --bind_ip 127.0.0.1 --logpath /var/log/mongodb/mongod.log --fork
cd /home/ubuntu/symbol/client/catapult/_build/bin
nohup ./catapult.server > /dev/null 2>&1 &
nohup ./catapult.broker .. &
cd /<install-dir>/symbol/client/rest/rest/
yarn start ./resouces/rest.json
```
http://\<ホスト\>:3000/chain/info/で同期が進んでいれば成功です。
起動方法がだいぶ面倒でしょうか？？
systemdでデーモン化するのはアリだと思います。私の場合、catapult.serverとcatapult.brokerはアップグレードぐらいでしか停止しないのでそのままnohup &で動かし、catapult-restだけデーモン化ツールのforeverで動かしています。

HTTPS化
===
いろいろな手法があります。bootstrapでの構成のようにプロキシを間に挟んだりするのも良いです。Catapult-RestがHTTPSに対応したようで、私はせっかくなので他のツールを導入することなくCatapult-Restで対応しました。

まずはLet's Encryptから証明書を取得します。
```bash
apt install certbot
certbot certonly --standalone
```
対話形式にドメインや管理用のメールアドレス登録をしていき、証明書を取得します。

restディレクトリを丸っとコピーします。
```bash
cd /<install-dir>/symbol/client/
cp -r rest/ ./rest-https
```

rest.jsonをhttps用に編集します。
```json
...
  "port": 3001,
  "protocol": "HTTPS",
  "sslKeyPath": "/etc/letsencrypt/live/<domain-name>/privkey.pem",
  "sslCertificatePath": "/etc/letsencrypt/live/<domain-name>/fullchain.pem",
...
```
上と同じようにyarn startしブラウザからhttps:/\<ホスト\>:3001/chain/infoで情報取得できれば成功です。

証明書更新はcertbotとhttps側Catapult-Restの再起動をcronで回すだけですが、メンテナンス編で書きます。