Symbol REST 2.5.1をNode.js 22でビルドする手順のメモです。
対象のDockerfileでは、Node.jsのデフォルトが20になっています。Node.js 20はすでにEOL(サポート終了)のため、Node.js 22でイメージを作り直す応急処置として試します。
Dockerfileの依存パッケージをインストールする処理を変更し、zeromq が依存する nan を 2.22.2 に固定します。作成したイメージは、Shoestringの設定に指定して利用します。
ここで紹介する確認は、Node.jsのバージョンとZeroMQモジュールの読み込みまでです。REST APIやWebSocket通知が正常に動作するか、継続して運用できるかは未確認です。
着手前に依存パッケージの動作を軽く確認する
Node.jsのメジャーバージョンを変更するため、先に主要な依存パッケージがNode.js 22で動作するか、検証用の環境で軽く確認しておく必要があります。対象のpackage.jsonで依存関係と各パッケージの対応Node.jsバージョンを確認し、インストールや読み込み、代表的な処理を試しておきます。特に zeromq のようなネイティブモジュールは、ビルドと読み込みの両方を確認します。
後述の require('zeromq') は、作成したイメージでの最低限の確認です。これだけですべての依存パッケージの互換性を確認できるわけではないため、ノードへ適用する前にはRESTの起動やAPI応答、WebSocket通知も検証環境で確認してください。
ソースコードを取得する
GitとDockerが利用できる環境で、対象のタグを指定して取得します。
git clone https://github.com/symbol/symbol.git -b rest/v2.5.1 --depth 1
cd symbol/client/rest/
以降の編集とビルドは、symbol/client/rest/ で行います。
なぜnanを2.22.2に固定するのか
zeromq@5.3.1 が依存する nan@2.17.0 のままでは、Node.js 22でのビルドに失敗します。そのため、今回は nan を 2.22.2 に固定します。
Dockerfileを変更する
vi Dockerfile
元のDockerfileにある、次の行を変更します。
RUN npm uninstall . && rm -rf node_modules && npm install --omit=dev
変更後は次のとおりです。
RUN npm pkg set "overrides.zeromq.nan=2.22.2" \
&& npm install --package-lock-only --ignore-scripts \
&& npm ci --omit=dev
npm pkg set で、zeromq 配下の nan に適用するバージョン指定を package.json に追加します。npmのoverridesは、このように依存先のパッケージのバージョンも指定できます。
続いてlockfileに変更を反映し、npm ci --omit=dev で開発用の依存パッケージを除いてインストールします。--ignore-scripts を付けるのはlockfile更新の段階だけです。最後の npm ci では、ネイティブモジュールのビルドに必要なインストールスクリプトを実行できるようにします。
なお、npm ciは既存の node_modules を削除してからインストールするため、変更後の処理では rm -rf node_modules を別に実行していません。
イメージをビルドする
ビルド引数でNode.js 22を指定します。
docker build \
--build-arg NODE_MAJOR=22 \
-t symbol-rest:2.5.1-node22 \
.
作成するイメージ名は symbol-rest:2.5.1-node22 です。Node.jsのメジャーバージョンを指定しているため、パッチバージョンはビルド時に取得されるものによって変わります。
Node.jsのバージョンを確認する
docker run --rm \
--entrypoint node \
symbol-rest:2.5.1-node22 \
--version
表示されたバージョンが v22. で始まることを確認します。
ZeroMQの読み込みを確認する
docker run --rm \
--entrypoint node \
symbol-rest:2.5.1-node22 \
-e "require('zeromq'); console.log('ZeroMQ OK')"
読み込みに成功すると、次の文字列が表示されます。
ZeroMQ OK
ZeroMQ OK と表示されれば、少なくともモジュールの読み込みは成功しています。ただし、このコマンドではSymbolノードへの接続やメッセージの送受信は行っていません。実際にちゃんと動くかどうかは、別途確認が必要です。
Shoestringに作成したイメージを指定する
ここからは、既存のShoestringのノード配置先で作業します。ビルドしたイメージが、そのノードを動かすDocker環境に存在していることが前提です。別のマシンでビルドした場合は、先にイメージを転送して読み込んでおきます。
使用中の shoestring.ini を開き、[images] セクションの rest を変更します。以下は該当箇所の抜粋です。
[images]
rest = symbol-rest:2.5.1-node22
同じセクションの client や mongo など、ほかの設定は残します。[images] の rest がREST用イメージの指定に使われることは、Shoestringの設定読み込み処理で確認できます。
設定後、Shoestringの upgrade コマンドを実行してCompose定義などを再生成します。ウィザードからアップグレードするとDockerイメージの指定が元に戻るため、今回は必ずコマンドで実行します。
コマンドのオプション指定を間違えると、既存の環境が壊れる可能性があります。実行前にノードを停止し、必ず keys/ と shoestring/ ディレクトリをバックアップしてください。
バックアップ先はノードの配置先とは別の場所とし、秘密鍵を含む keys/ は第三者がアクセスできない場所で保管します。
また、既存のCompose定義や userconfig/ を削除して作り直す処理なので、これらも復旧用に保存しておきます。upgradeの実装も参照してください。
たとえば、Mainnetで、設定が shoestring/shoestring.ini、独自設定が shoestring/overrides.ini、配置先がカレントディレクトリの場合は次の形です。ShoestringをインストールしたPython環境で実行します。
python3 -m shoestring upgrade \
--config shoestring/shoestring.ini \
--overrides shoestring/overrides.ini \
--directory . \
--package mainnet
ネットワーク、設定ファイル、独自設定ファイル、配置先は使用中の環境に合わせます。--rest-overrides も使用している場合は、更新時にも同じ指定を引き継いでください。
更新後は docker compose config でRESTサービスのイメージが symbol-rest:2.5.1-node22 になっていることを確認してから、ノードを起動します。
起動後はログ、REST APIの応答、WebSocketでのブロック通知を確認します。モジュールの読み込み確認だけで、ノードとしての動作確認を済ませたことにはしないようにします。