はじめに
RaspberryPiでSymbolNodeを構築してみました。
非エンジニアが四苦八苦しながらなんとかノード起動まで漕ぎ着けました。
正直甘くみていました。
辿り着けたのも、先人の知恵やアドバイスのおかげです。
ありがとうございます。
加えて、QUESTにて応援していただいた皆様にも感謝申し上げます。
ありがとうございます。
参考にさせていただいたページ
ちなみにXYMが全然足りないのでテストネットで稼働させています。
何がとは言いませんが、
NACW73ZWAD6RGZPC3P64DN3KYK5XDLLMVGHW2KQ
私のsymbolアドレスです。
使ったもの
M1 Mac
RapberryPi 4B 8GB
1TB SSD(USBのやつ)
テキトーなSDカード
テキトーなモニタ
テキトーなキーボード
1 OS起動まで
1-1 Raspberry Pi Imagerをインストール
1-2 USBブート、できるかな?
めんどければこの確認作業は飛ばして1-3から始めてもいい。で、うまくいかなければ戻ってきて確認とアップデートをするとか。
Raspberry Pi 4B からUSBブートに対応したらしい。
ただし、ブートローダが古いとダメなので、ブートローダを更新する必要がある。
確認は、一旦テキトーなSDカードにRaspbianというOSをインストールして
sudo vcgencmd bootloader_version
をすると、
update-time XXXXXXXX
とかいうのが出てくる。これはUNIXタイムなので、「UNIX TIME 変換」とか検索すれば変換サイトが出てくる。
2020年12月11日のアップデートでUSBブートに正式対応したのでそれ以降のバージョンであれば出来るとは思う。
1-3 OSイメージのダウンロード
1-4 書き込み
「カスタムイメージを使う」で 1-3 でダウンロードしたイメージを選択
SSDをMacに挿し、
「ストレージを選ぶ」で挿したSSDを選択。
歯車のマークで、ユーザー設定とかWi-Fi設定とかできるのでやっとく。一応ちゃんと反映されてた。
最後に「書き込む」を押して少し待てばOK。
1-5 起動
以下の作業をやらないとWiFiが繋がらなかった(なぜだ)。
・RaspberryPiにSSDを挿し、モニタとキーボードを接続。
・それから電源に繋ぐ。
・一旦ログインする。
ここまで来ればWiFiが繋がるのでssh接続で今後はいく。
ssh ユーザ名@IPアドレス
2 セキュリティって大事だよね
2-1 アップデート
sudo apt update
sudo apt upgrade
アップデートの内容によっては設定ファイルを初期化するものもあるので、この段階でやっておくといい。
2-2 ルートにパスワードを設定
sudo passwd root
2-3 新たなユーザーを作成
デフォルトユーザの場合は新たなユーザーを作る
sudo su
このコマンドで一旦ルートユーザーになる
adduser ユーザ名
このコマンドで新たなユーザーを作る。パスワードを設定した後、フルネームとかを聞かれるが、空白のままエンターでOK。
2-4 作ったユーザーをsudoグループに追加し、権限を持たせる
gpasswd -a ユーザ名 sudo
2-5 データ移行と移動ログインの解除
省略
2-6 初期ユーザの削除
一旦ログアウトし、新たに作ったユーザでログインして、次のコマンドを実行。
sudo userdel -r ユーザ名
2-7 ssh設定の変更
sudo nano /etc/ssh/sshd_config
これでsshの設定を変える。(自分はnano派だが、viを使っても良い)
#Port 22 -> Port 好きなポート番号
気休め程度だがポート番号を変える
#PermitRootLogin prohibit-password -> PermitRootLogin no
ルートログインを禁止する
#PermitEmptyPasswords no -> PermitEmptyPasswords no
これもついでにやっとく
sudo /etc/init.d/ssh restart
これでsshを再起動し、設定を反映させる
2-8 IPアドレスの制限
省略
2-9 公開鍵でログインする
logout
一旦ログアウトする。ここからはMacでの作業。
ssh-keygen -t rsa -b 4096
このコマンドで鍵ペアを作る。
サイトによっては2048で鍵ペアを作っているみたいだが、rsaの場合は強度的に4096がいいらしい。
パスフレーズ(この鍵を使う時に聞かれるパスワードという認識でとりあえずはいい)を聞かれるので、好きなものを設定する(忘れないようにする。)
ls -al ~/.ssh
これで、「id_rsa」「id_rsa.pub」ができているのを確認。
id_rsaが秘密鍵
id_rsa.pubが公開鍵
ssh-copy-id -i ~/.ssh/id_rsa.pub -p ポート番号 ユーザ名@IPアドレス
これでraspberry pi に公開鍵を送信・登録を行う。
うまくいかない時はsudoをつける。
ssh -p ポート番号 -i id_rsa ユーザ名@IPアドレス
これでログインする。
うまくいかない時はsudoをつける。
ここからはraspberry piでの作業。
2-10 パスワードでログインできないようにする
sudo nano /etc/ssh/sshd_config
もっかいこのファイルを操作し、
#PasswordAuthentication yes -> PasswordAuthentication no
こんな感じに変更
3 インストール
sudo apt-get install -y nodejs npm
sudo npm install -g npm@latest
sudo apt install -y docker.io
sudo apt install -y docker-compose
sudo usermod -aG docker ユーザ名
su - ユーザ名
これらのコマンドを順に実行する。
sudo reboot
自分は念のためここで一旦再起動させた。
ここまでが準備運動。ここからが構築本番。
4 構築その1
めんどいので処理をシェルスクリプトにまとめた。
nano ~/テキトーなファイル名.sh
をやって、以下の内容を貼り付ける。
#!/bin/bash
baseFolderName="mysymbol"
check=""
echo "********** Symbolリポジトリのクローン"
rm -rf symbol
git clone https://github.com/symbol/symbol.git
cd symbol
git checkout -b 1.0.3.5 refs/tags/client/catapult/v1.0.3.5
echo "********** コンフィグファイルの作成"
echo "compiler: ../compilers/gcc-latest.yaml" > ./jenkins/catapult/configurations/gcc-12-aarch64.yaml
echo "architecture: armv8-a" >> ./jenkins/catapult/configurations/gcc-12-aarch64.yaml
check=`docker images | grep symbol-server-compiler`
while [ "$check" = "" ]
do
echo "********** ベースとなるDockerイメージの作成 1/2"
echo -e "\
FROM arm64v8/ubuntu:22.04 \n\
\n\
ARG DEBIAN_FRONTEND=noninteractive \n\
\n\
RUN apt-get update >/dev/null && \\ \n\
apt-get install -y \\ \n\
apt-utils \\ \n\
build-essential \\ \n\
gnupg2 \\ \n\
curl \\ \n\
xz-utils \\ \n\
wget \\ \n\
>/dev/null \n\
\n\
\n\
ARG COMPILER_VERSION=12 \n\
RUN apt-get update >/dev/null && \\ \n\
apt-get install -y \\ \n\
gcc-\${COMPILER_VERSION} g++-\${COMPILER_VERSION} >/dev/null && \\ \n\
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-\${COMPILER_VERSION} 100 && \\ \n\
update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-\${COMPILER_VERSION} 100 && \\ \n\
update-alternatives --install /usr/bin/cc cc /usr/bin/gcc 100 && \\ \n\
update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++ 100 && \\ \n\
update-alternatives --install /usr/bin/gcov gcov /usr/bin/gcov-\${COMPILER_VERSION} 100 && \\ \n\
update-alternatives --install /usr/bin/gcov-dump gcov-dump /usr/bin/gcov-dump-\${COMPILER_VERSION} 100 && \\ \n\
update-alternatives --install /usr/bin/gcov-tool gcov-tool /usr/bin/gcov-tool-\${COMPILER_VERSION} 100 && \\ \n\
rm -rf /var/lib/apt/lists/* \
" > jenkins/catapult/compilers/ubuntu-gcc/Dockerfile-ubuntu-gcc-12
echo "********** ベースとなるDockerイメージの作成 2/2"
docker build -f jenkins/catapult/compilers/ubuntu-gcc/Dockerfile-ubuntu-gcc-12 -t $baseFolderName/symbol-server-compiler:ubuntu-gcc-12 .
check=`docker images | grep symbol-server-compiler`
done
echo "********** runDockerBuild.pyを修正"
sed -i -e s/symbolplatform/$baseFolderName/g \
-e s/"--source-path=\/catapult-src\/client\/catapult"/"--source-path=\/catapult-src\/catapult"/g \
-e s/"f'registry.hub.docker.com\/{prepare_replacements\[\"base_image_name\"\]}'"/"f'{prepare_replacements\[\"base_image_name\"\]}'"/g \
-e s/"environment_manager.copy_tree_with_symlinks(source_path \/ 'client\/catapult' \/ folder_name, folder_name)"/\
"environment_manager.copy_tree_with_symlinks(source_path \/ 'catapult' \/ folder_name, folder_name)"/g \
jenkins/catapult/runDockerBuild.py
echo "********** environment.pyの修正"
sed -i -e s/"for descriptor in \[('ubuntu', '\/usr\/lib\/x86_64-linux-gnu'), ('fedora', '\/usr\/lib64')\]:"/\
"for descriptor in \[('ubuntu', '\/usr\/lib\/aarch64-linux-gnu'), ('fedora', '\/usr\/lib64')\]:"/g \
jenkins/catapult/environment.py
check=`docker images | grep preimage1`
while [ "$check" = "" ]
do
echo "********** 中間イメージ1 1/2"
python3 ./jenkins/catapult/baseImageDockerfileGenerator.py \
--compiler-configuration jenkins/catapult/configurations/gcc-12-aarch64.yaml \
--operating-system ubuntu \
--versions ./jenkins/catapult/versions.properties \
--layer os \
| sed -e s/symbolplatform/$baseFolderName/g \
-e s/cmake-3.23.2-Linux-x86_64.sh/cmake-3.24.3-linux-aarch64.sh/g \
-e s/v3.23.2/v3.24.3/g \
> Dockerfile-preimage1
echo "********** 中間イメージ1 2/2"
docker build -f Dockerfile-preimage1 -t $baseFolderName/symbol-server-build-base:ubuntu-gcc-12-armv8-a-preimage1 .
check=`docker images | grep preimage1`
done
check=`docker images | grep preimage2`
while [ "$check" = "" ]
do
echo "********** 中間イメージ2 1/2"
python3 ./jenkins/catapult/baseImageDockerfileGenerator.py \
--compiler-configuration jenkins/catapult/configurations/gcc-12-aarch64.yaml \
--operating-system ubuntu \
--versions ./jenkins/catapult/versions.properties \
--layer boost \
| sed -e s/symbolplatform/$baseFolderName/g \
> Dockerfile-preimage2
echo "********** 中間イメージ2 1/2"
docker build -f Dockerfile-preimage2 -t $baseFolderName/symbol-server-build-base:ubuntu-gcc-12-armv8-a-preimage2 .
check=`docker images | grep preimage2`
done
check=`docker images | grep preimage3`
while [ "$check" = "" ]
do
echo "********** 中間イメージ3 1/2"
python3 ./jenkins/catapult/baseImageDockerfileGenerator.py \
--compiler-configuration jenkins/catapult/configurations/gcc-12-aarch64.yaml \
--operating-system ubuntu \
--versions ./jenkins/catapult/versions.properties \
--layer deps \
| sed -e s/symbolplatform/$baseFolderName/g \
-e s/"Configure linux-x86_64"/"Configure linux-aarch64"/g \
> Dockerfile-preimage3
echo "********** 中間イメージ3 2/2"
docker build -f Dockerfile-preimage3 -t $baseFolderName/symbol-server-build-base:ubuntu-gcc-12-armv8-a-preimage3 . --memory-swap -1
check=`docker images | grep preimage3`
done
check=`docker images | grep ubuntu-gcc-12-armv8-a$'\s'`
while [ "$check" = "" ]
do
echo "********** 最終レイヤー 1/2"
python3 ./jenkins/catapult/baseImageDockerfileGenerator.py \
--compiler-configuration jenkins/catapult/configurations/gcc-12-aarch64.yaml \
--operating-system ubuntu \
--versions ./jenkins/catapult/versions.properties \
--layer test \
| sed -e s/symbolplatform/$baseFolderName/g \
-e s/"Configure linux-x86_64"/"Configure linux-aarch64"/g \
> Dockerfile-preimage4
echo "最終レイヤー 2/2"
docker build -f Dockerfile-preimage4 -t $baseFolderName/symbol-server-build-base:ubuntu-gcc-12-armv8-a .
check=`docker images | grep ubuntu-gcc-12-armv8-a$'\s'`
done
check=`docker images | grep symbol-server-test-base`
while [ "$check" = "" ]
do
echo "********** symbol-server-test-baseイメージを作成 1/2"
echo -e "\
FROM arm64v8/ubuntu:22.04 \n\
CMD ["/bin/bash"] \n\
ARG DEBIAN_FRONTEND=noninteractive \n\
\n\
RUN apt-get -y update \ \n\
&& apt-get install -y bison gdb git flex python3 python3-ply python3-pip shellcheck inotify-tools libdw-dev libelf-dev libiberty-dev libslang2-dev \ \n\
&& rm -rf /var/lib/apt/lists/* \ \n\
&& pip3 install -U colorama cryptography gitpython pycodestyle pylint pylint-quotes PyYAML \ \n\
&& git config --global http.postBuffer 524288000 \ \n\
&& git config --global https.postBuffer 524288000 \ \n\
&& git clone --depth 1 https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git linux.git \ \n\
&& cd linux.git/tools/perf \ \n\
&& make \ \n\
&& cp perf /usr/bin \ \n\
&& cd ../../.. \ \n\
&& rm -rf linux.git \
" > Docker-test-preimage
echo "********** symbol-server-test-baseイメージを作成 2/2"
docker build -f Docker-test-preimage -t $baseFolderName/symbol-server-test-base:ubuntu .
check=`docker images | grep symbol-server-test-base`
done
check=`docker images | grep symbol-server$'\s'`
while [ "$check" = "" ]
do
echo "********** クライアントのコンパイル"
sudo mkdir /jenkins_cache
sudo chown 1000:1000 /jenkins_cache
python3 jenkins/catapult/runDockerBuild.py \
--compiler-configuration jenkins/catapult/configurations/gcc-12-aarch64.yaml \
--build-configuration jenkins/catapult/configurations/release-private.yaml \
--operating-system ubuntu \
--user "$(id -u):$(id -g)" \
--source-path client \
--destination-image-label gcc-12-armv8-a-main-9273d6c5
# うまくいかなかったのでハードコーディング
docker tag mysymbol/symbol-server-private:gcc-12-armv8-a-main-9273d6c5 mysymbol/symbol-server:gcc-1.0.3.5
check=`docker images | grep symbol-server$'\s'`
done
echo "********** restイメージ 1/3"
cd ./client
mv ./rest ./rest_old
git clone https://github.com/symbol/symbol.git -b rest/v2.4.2
cp -r ./symbol/client/rest ./
rm -rf symbol
echo "********** restイメージ 2/3"
cd ./rest
cat ./Dockerfile | sed s/lts/16/g > ./Dockerfilev2
echo "********** restイメージ 3/3"
docker build -f ./Dockerfilev2 -t $baseFolderName/symbol-rest:2.4.2 .
echo "********** Node.js を最新バージョンにする"
sudo npm install -g n
sudo n latest
check=`symbol-bootstrap version | grep node`
while [ "$check" = "" ]
do
echo "********** symbol-bootstrapのインストール"
sudo npm install -g symbol-bootstrap
echo "コンテナイメージの変更"
sudo cp /usr/local/lib/node_modules/symbol-bootstrap/presets/shared.yml /usr/local/lib/node_modules/symbol-bootstrap/presets/shared_old.yml
sudo sed -i -e s/"symbolServerImage: symbolplatform"/"symbolServerImage: "$baseFolderName/g \
-e s/"symbolRestImage: symbolplatform"/"symbolRestImage: "$baseFolderName/g \
/usr/local/lib/node_modules/symbol-bootstrap/presets/shared.yml
check=`symbol-bootstrap version | grep node`
done
bash テキトーなファイル名.sh
これで実行。
おそらく大丈夫なハズ。
baseFolderName=
は好きな名前を入れられたい。
ネットワークが貧弱だとイメージ作成が失敗することがあるので上手くいくまでループさせている。
素人が書いたスクリプトなので、雑な部分は大いにある。
peerノードでいい人は
echo "********** restイメージ 1/3"
から始まるrestイメージの部分は削除してもいい。
docker images
スクリプト実行後はこれで作成済みのDockerのイメージが見られるので、全て作成されたか確認
5 DDNSの設定
このサイトのとおりやった。感謝。
6 symbol-bootstrap
細かな設定は他サイトを参照されたい。
6-1 設定ファイルの作成1
cd ~/symbol
で移動し、
symbol-bootstrap wizerd
で設定ファイルを作る。
~/symbol/custom-preset.yml
があることを確認したら
nano ~/symbol/custom-preset.yml
で、末尾に
symbolServerImage: シェルスクリプトで設定した(baseFolderNameの)名前/symbol-server:gcc-1.0.3.4
symbolRestImage: シェルスクリプトで設定した(baseFolderNameの)名前/symbol-rest:2.4.2 #先程作成したイメージ名
を追加。
6-2 設定ファイルの作成2
symbol-bootstrap config -p testnet -a dual -c custom-preset.yml
を実行。メインネットがいい人は testnetをmainnetに変更すること。
symbol-bootstrap compose
を実行。
6-3 起動
symbol-bootstrap run -d
を実行し、ノードを起動。
symbol-bootstrap healthCheck
で、正常に作動しているかが確認できる。
終わりに
NACW73ZWAD6RGZPC3P64DN3KYK5XDLLMVGHW2KQ
しつこいようですが私のsymbolアドレスです。