Heroku で動かす Node-RED にパスワード設定しノード追加インストールにも対応するメモ(npm prefix アプローチ)

Heroku で動かす Node-RED にパスワード設定しノード追加インストールにも対応するよう npm prefix アプローチでやってみます。

使っている以前のナレッジ

試行錯誤をつづけているため、ナレッジが多くなっていますが、以下のような流れをたどっています。

ざっくりいうと、Node-RED をあるローカルのフォルダだけで動くようにプロジェクトを作る設定で Heroku で動かせてパスワード設定までできるようにはなったんですが、エディタ画面でノードの追加インストールがうまくいかなくなったので、動かすようにしました。

そして、Heroku 用に Node-RED をプロジェクトフォルダ配下で Node-RED エディタ画面でノードの追加インストールも動くようにするメモ では、フォルダ構造自体を変えて対処したけど、もともとのサブフォルダ node-red_dir にまとめる形でやりたかったんですね。

それが、以下の記事の npm prefix でやれば実現できそうなのでやってみます。

サブフォルダにある package.json で npm install したいときの prefix オプションを実験してうまくいったメモ

手元にフォルダを作る

image

まず、なるべく素の状態からということで、heroku-node-red-test2 という空フォルダを作り Visual Studio Code でプロジェクトとして開きます。

Git の初期設定

git init

で Git 対象のフォルダにします。

.gitignore ファイルを作る

プロジェクトフォルダ直下で、 .gitignore ファイルを作ります。

node_modules

1行ですがこちらを書いておきます。

npm の初期設定

npm init -y

でプロジェクトフォルダに

このあたりのナレッジを組み合わせつつ、こちらの package.json で行きます。 2021/10/02 現在。

{
  "name": "heroku-node-red-test2",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "heroku":"npm run heroku:subdir-install && heroku:auth-launch",
    "heroku:auth-launch": "node-red -u ./node-red_dir -s ./node-red_dir/settings.js",
    "heroku:subdir-install":"npm --prefix ./node-red_dir install ./node-red_dir",
    "node-red": "./node_modules/.bin/node-red -p 18801 -u ./node-red_dir -s ./node-red_dir/settings.js -D adminAuth=null",
    "init": "npm run init:mkdir && npm run init:get-settings.js",
    "init:mkdir": "node -e \"console.log('[START] mkdir-node-red_dir');const fs = require('fs');const path_nodered_dir = './node-red_dir';if (fs.existsSync(path_nodered_dir)) {console.log( '[ALERT] ' + path_nodered_dir + ' has existed!');} else {console.log('[OK] mkdir -> ' + path_nodered_dir );fs.mkdirSync(path_nodered_dir);}\"",
    "init:get-settings.js": "node -e \"const url = 'https://raw.githubusercontent.com/node-red/node-red/master/packages/node_modules/node-red/settings.js';const stream_output_path = './node-red_dir/settings.js';if (fs.existsSync(stream_output_path)) {console.log( '[ALERT] ' + stream_output_path + ' has existed!');} else {console.log('[START] download settings.js ...');const https = require('https');const fs = require('fs');const stream = fs.createWriteStream(stream_output_path);https.get(url, function(res){res.pipe(stream);res.on('end', function () {stream.close();console.log('[OK] got settings.js! -> ' + stream_output_path);});});}\""
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

以前、一時的にしのいでいた Heroku 公開時はエディタをOFF にするような設定を削除したり、scripts 内の名称を調整したりしました。

npm run init で Node-RED 関連の準備

npm run init

のコマンドで Node-RED の設定を集める node-red_dir であったり、設定ファイル setting.js なりを自動で準備します。

Node-RED インストール

npm i node-red

コマンドで Node-RED インストール。package.json に書いてもいいですが、固定のバージョンになってしまうので、いちいち入れてます。(最新をなるべく使いたい)

ひとまず動かしてみる

npm run node-red

で、動かしてみます。

image

http://127.0.0.1:18801/ で表示できました。

簡単な HTTP in をつくる

image

このようなフローをデプロイして /api1 でアクセスすると、返答するものをつくります。

[{"id":"0a02324a2c7b357e","type":"http in","z":"2c233af411932df1","name":"","url":"/api1","method":"get","upload":false,"swaggerDoc":"","x":170,"y":240,"wires":[["f40e5c6c4cbfd700","0d089f742d65a107"]]},{"id":"f40e5c6c4cbfd700","type":"http response","z":"2c233af411932df1","name":"","statusCode":"","headers":{},"x":410,"y":240,"wires":[]},{"id":"0d089f742d65a107","type":"debug","z":"2c233af411932df1","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":430,"y":180,"wires":[]}]

このようなフローです。

Procfile ファイルで Heroku の動作を決める

Heroku CLI はインストールされ Heroku CLI は Heroku アカウントでログインして使える状態になっている前提で進めます。

Procfile をプロジェクトフォルダ直下に作成して以下のようにします。

web: npm run heroku

今回の heroku コマンドの中は "heroku":"npm run heroku:subdir-install && heroku:auth-launch", になっていて、heroku:subdir-install でサブフォルダの npm i インストール、パスワード付きの起動 heroku:auth-launch が行われています。

パスワードや管理画面のパスを調整

プロジェクトフォルダ直下に集約した Node-RED を動かした Heroku にパスワード設定するメモ を元にパスワードや管理画面のパスを調整します。

setting.js の adminAuth を編集

node-red_dir/setting.js の adminAuth パラメータを以下のように編集します。adminAuth パラメータがコメントアウトされているところを上書きします。

    adminAuth: {
      type: "credentials",
      users: function(username) {
        return new Promise(function(resolve) {
          // ここでユーザ名が許可されたユーザかどうかを
          // チェックする処理を行う
          if (process.env.NODERED_LOGIN_ID == username) {
            // ユーザ名が存在すればユーザオブジェクトを返す。
            // 'username' と 'permissions' プロパティは必須です。
            var user = { username: process.env.NODERED_LOGIN_ID, permissions: "*" };
            resolve(user);
          } else {
            // ユーザ名が存在しない場合はnullを返す。
            resolve(null);
          }
        });
      },
      authenticate: function(username, password) {
        return new Promise(function(resolve) {
          // ここでユーザー名/パスワードの組み合わせを
          // チェックする処理を行う
          if (process.env.NODERED_LOGIN_ID == username &&
            process.env.NODERED_LOGIN_PASSWORD == password) {
              // ユーザー名/パスワードの組み合わせが有効な場合はユーザオブジェクトを返す。
              // users(username);を呼び出すのと同様です。
              var user = { username: process.env.NODERED_LOGIN_ID, permissions: "*" };
              resolve(user);
          } else {
              // ユーザー名/パスワードの組み合わせが無効な場合は
              // nullを返す。
              resolve(null);
          }
        });
      }
    },

process.env.NODERED_LOGIN_IDprocess.env.NODERED_LOGIN_PASSWORD は、先ほど設定した Heroku の環境変数を呼び出して判定しています。

httpAdminRoot を設定して Node-RED エディタの URL を /admin に

node-red_dir/setting.js の httpAdminRoot を以下のように編集します。adminAuth パラメータがコメントアウトされているところを上書きします。

httpAdminRoot: '/admin',

エディタがアクセスしてすぐに見えるのもよくないので、エディタUIのためのルートURLを /admin にズラします。

変更内容をインデックスに追加してコミット対象にする

.gitinnore で node_modules が除外されていることを念入りに確認しましょう。

git add .

で、変更内容をインデックスに追加してコミット対象にします。

git commit -m "init"

コミット対象にしたらコミットします。

もちろん、Visual Studio Code の場合は SOURCE CONTROL のほうで GUI からインデックス追加とコミット対応してもOKです。

Heroku にアプリ作成

プロジェクトフォルダ直下で Herolu CLI のコマンドを実行して Heroku にアプリ作成します。

heroku create <サーバー名>

<サーバー名> は自分の作りたい名前にしましょう。

Heroku に反映

git push heroku master

で Heroku 側に push してアプリに反映します。master でうまく行かない場合は main で試してみてください。(このあたり、どこでメインブランチの名前が決まるか分かっていないです)

image

うまくいけば、このようにプッシュされアプリが反映されます。

Heroku の環境変数を設定する

設定と環境設定 | Heroku Dev Center

を、参考に Heroku Dashboard で、

image

アプリの Settings タブから、

image

環境変数の値でログイン ID とログインパスワード を用意します。

  • NODERED_LOGIN_ID
    • ログイン ID
  • NODERED_LOGIN_PASSWORD
    • ログインパスワード

と設定しました。

Heroku で確認してみる

https://<今回のHerokuアドレス>/admin でアクセスしてみましょう。

image

無事アクセスできました。

もちろん、Heroku の環境変数設定した、IDとパスワードでログインできるかも確認できました!

手元の Node-RED で追加インストールしてみる

image

サブフォルダにある package.json で npm install したいときの prefix オプションを実験してうまくいったメモ で、追加インストールされた場合も heroku:subdir-install 内で "heroku:subdir-install":"npm --prefix ./node-red_dir install ./node-red_dir", というコマンドで node-red_dir 内の npm インストールが走るはずなのでテストしてみます。

image

手元の Node-RED で、多めのノードインストールが行われそうな node-red-dashboard をインストールしました。

image

こんなかんじ。

image

ダッシュボードのグループやタブを設定して button ノードを加えてみました。

image

これをもう一度コミットし Heroku に反映します。

image

Heroku でエディタを見てみると、同じように反映されていましたし。

image

パレットもダッシュボードノード一式がいました!無事に、サブフォルダ追加インストールが Heroku 側で動いてますね!

これで、最近、あれこれやっていた Heroku の設定が一旦落ち着きました。あとは使いながらブラッシュアップしていこうと思います。