• V
 

Dockerで実行する

このガイドはDockerおよびDockerコマンドラインに対していくらか基本的な知識を持っていることを前提としています。 ここにはDockerでNode-REDを実行する多くの方法が記述されており、複数のアーキテクチャ(amd64、arm32v6、arm32v7、arm64v8およびs390x)をサポートしています。

Docker Hubに存在する現在のNode-RED 1.0のリポジトリは、 nodered/node-redにリネームされています。

クイックスタート

最も簡単な方法によってDockerで実行するには、次のようにします:

    docker run -it -p 1880:1880 -v node_red_data:/data --name mynodered nodered/node-red

このコマンドを詳細に見てみましょう:

    docker run              - run this container, initially building locally if necessary
    -it                     - attach a terminal session so we can see what is going on
    -p 1880:1880            - connect local port 1880 to the exposed internal port 1880
    -v node_red_data:/data  - mount the host node_red_data directory to the container /data directory so any changes made to flows are persisted
    --name mynodered        - give this machine a friendly local name
    nodered/node-red        - the image to base it on - currently Node-RED v1.2.0

コマンドを実行するとNode-REDのインスタンスを実行するターミナルウィンドウが開かれます。

    Welcome to Node-RED
    ===================

    10 Oct 12:57:10 - [info] Node-RED version: v1.2.0
    10 Oct 12:57:10 - [info] Node.js  version: v10.22.1
    10 Oct 12:57:10 - [info] Linux 4.19.76-linuxkit x64 LE
    10 Oct 12:57:11 - [info] Loading palette nodes
    10 Oct 12:57:16 - [info] Settings file  : /data/settings.js
    10 Oct 12:57:16 - [info] Context store  : 'default' [module=memory]
    10 Oct 12:57:16 - [info] User directory : /data
    10 Oct 12:57:16 - [warn] Projects disabled : editorTheme.projects.enabled=false
    10 Oct 12:57:16 - [info] Flows file     : /data/flows.json
    10 Oct 12:57:16 - [info] Creating new flow file
    10 Oct 12:57:17 - [warn]

    ---------------------------------------------------------------------
    Your flow credentials file is encrypted using a system-generated key.

    If the system-generated key is lost for any reason, your credentials
    file will not be recoverable, you will have to delete it and re-enter
    your credentials.

    You should set your own key using the 'credentialSecret' option in
    your settings file. Node-RED will then re-encrypt your credentials
    file using your chosen key the next time you deploy a change.
    ---------------------------------------------------------------------

    10 Oct 12:57:17 - [info] Starting flows
    10 Oct 12:57:17 - [info] Started flows
    10 Oct 12:57:17 - [info] Server now running at http://127.0.0.1:1880/

    [...]

ブラウザでhttp://{host-ip}:1880を開くと、馴染みのNode-REDのデスクトップを確認できます。

これをおこなう利点は命名する(mynodered)ことでより簡単に操作することができ、 ホストポートを修正することで慣れ親しんでいる画面にたどり着くことができます。 もちろんこれは同時に1つのインスタンスしか実行できないことを意味します…しかし、一度に1ステップずつ実行できます。

現在実行しているものに満足した場合、Ctrl-p Ctrl-qによってターミナルを切り離すことができます - コンテナはバックグラウンドで実行させ続けます。

ターミナルに再接続する(ログを確認する)ためには、以下を実行します:

docker attach mynodered

コンテナを再起動する必要がある場合(例 Dockerデーモンのリブート再起動):

docker start mynodered

そして必要なときに再び停止します:

docker stop mynodered

イメージのバリエーション

Node-REDイメージは、可能な限り小さく保つためにofficial Node JS Alpine Linuxイメージに基づいています。 Alpine Linuxを使用するとビルドされるイメージのサイズを小さくすることができますが、ネイティブモジュールのコンパイルに必要な一般的な依存関係は除去されています。これらの依存関係を加えたい場合、実行しているコンテナで除外したパッケージでNode-REDイメージを拡張するか、docker-customを参考に新たなイメージをビルドします。

詳細なイメージ、タグ、マニフェスト情報についてはGithub project READMEを参照してください。

例えば: アーキテクチャとしてarm32v7を持つRaspberry PI 3Bで実行するとしましょう。そして、以下のコマンドでイメージ(1.2.0-10-arm32v7とタグ付けされた)をプルし、コンテナを起動します。

docker run -it -p 1880:1880 -v node_red_data:/data --name mynodered nodered/node-red:latest

同じコマンドはamd64システムで実行している場合でも利用することができますが、これはDockerがamd64ホストで実行されていることを検出し、一致するタグ(1.2.0-10-amd64)のイメージをプルするからです。

これは自身が実行しているアーキテクチャを知る/指定する必要がないという利点を有しており、docker runコマンドとDockerコンポーズファイルをより柔軟に、システム間の互換を可能にします。

Note: 現在Dockerのアーキテクチャ検出に、arm32v6 - 例えばRaspberry Pi Zeroまたは1について失敗するというバグがあります。現状、以下のようにこれらのデバイスではフルイメージタグを指定する必要があります。:

docker run -it -p 1880:1880 -v node_red_data:/data --name mynodered nodered/node-red:1.2.0-10-arm32v6

ユーザデータを管理する

DockerでNode-REDを実行する場合、 コンテナが壊れた場合に追加したノードやフローが消失しないことを保証する必要があります。 コンテナ外部のボリュームに対してデータディレクトリをマウンティングすることで、このユーザデータを永続化することができます。 バインドしたマウントまたは命名したデータボリュームを使うことでおこなうこともできます。

Node-REDはコンテナ内の/dataディレクトリを使うことでユーザ設定データを保存できます。

永続化のためにホストディレクトリを利用する(マウントをバインドする)

コンテナ内部のNode-REDのユーザディレクトリを、コンテナ外部のホストディレクトリに保存することで、以下のコマンドを使うことができます。 このホストディレクトリにアクセスを許可すると、 コンテナ内のnode-redユーザ(デフォルトではuid=1000)はホストディレクトリのオーナーとして同じuidを持っているはずです。

docker run -it -p 1880:1880 -v /home/pi/.node-red:/data --name mynodered nodered/node-red

この例ではホストの/home/pi/.node-redディレクトリをコンテナの/dataディレクトリにバインドします。

Note: バージョン0.20から1.0に移行したユーザは存在している/dataディレクトリが正しいオーナー権限を持っていることを確認する必要がある。 1.0では、1000:1000となる必要があります。 コマンドsudo chown -R 1000:1000 path/to/your/node-red/dataによって強制的に変更することができます。

権限に関する詳細な情報については、 wikiを参照してください。

命名されたデータボリュームを利用する

Dockerも命名されたデータボリュームを使うことがサポートされており、 コンテナ外部で永続化または共有するデータを保存することができます。

ユーザデータを永続化するために新たに命名されたデータボリュームを作成し、 このボリュームを使って新たなコンテナを実行します。

$ docker volume create --name node_red_user_data
$ docker volume ls
DRIVER              VOLUME NAME
local               node_red_user_data
$ docker run -it -p 1880:1880 -v node_red_user_data:/data --name mynodered nodered/node-red

マウントしたボリュームからデータのバックアップを取る必要がある場合、コンテナを実行中にアクセスします。

$ docker cp  mynodered:/data  /your/backup/directory

いくつかのサンプルフローを作成してデプロイするためにNode-REDを使ったあと、 コンテナを壊してユーザデータを喪失することなく新しいインスタンスを起動します。

$ docker stop mynodered
$ docker rm mynodered
$ docker run -it -p 1880:1880 -v node_red_user_data:/data --name mynodered nodered/node-red

更新する

/dataは現在コンテナの外部に保存されているため、 ベースのコンテナイメージを更新することはシンプルです。

$ docker pull nodered/node-red
$ docker stop mynodered
$ docker rm mynodered
$ docker run -it -p 1880:1880 -v node_red_user_data:/data --name mynodered nodered/node-red

Dockerスタック / Dockerコンポーズ

以下のDockerコンポーズファイルの例はdocker stackまたはdocker-composeによって実行できます。 Docker stackおよびDocker composeに関する更なる情報は公式Dockerページを参照してください。

################################################################################
# Node-RED Stack or Compose
################################################################################
# docker stack deploy node-red --compose-file docker-compose-node-red.yml
# docker-compose -f docker-compose-node-red.yml -p myNoderedProject up
################################################################################
version: "3.7"

services:
  node-red:
    image: nodered/node-red:latest
    environment:
      - TZ=Europe/Amsterdam
    ports:
      - "1880:1880"
    networks:
      - node-red-net
    volumes:
      - node-red-data:/data

volumes:
  node-red-data:

networks:
  node-red-net:

上述のコンポーズファイルは以下のことをおこないます:

  • node-redサービスを作成
  • 最新版node-redイメージをプル
  • ヨーロッパ/アムステルダムにタイムゾーンを設定
  • コンテナポート1880をホストポート1880に設定
  • node-red-netネットワークを作成、このネットワークにコンテナを接続
  • コンテナ内の/dataディレクトリをDockerのnode-red-dataボリュームに永続化

ローカルリソースにDockerファイルをコピーする

ローカルディレクトリからファイルをNode-REDのDockerイメージに移すことはしばしば有効です(例えば、gitリポジトリにプロジェクト全体を保存したい場合)。これを実施するには、ローカルディレクトリを以下のような構成にするはずです:

Dockerfile
README.md
package.json     # 自身のフローが必要とする追加ノードをpackage.jsonに追加します
flows.json       # 一般的にNode-REDがフローを保存するファイル
flows_cred.json  # フローに必要になるかもしれない資格情報
settings.js      # 自分の設定ファイル

NOTE: 外部の/dataボリュームにマウントしたい場合、この方法は不適切です。永続化のために外部のボリュームを使う必要がある場合、代わりに設定ファイルとフローファイルをそのボリュームにコピーします。

以下のDockerファイルをベースとなるNode-RED Dockerイメージ上でビルドし、加えてそのイメージに自身が利用しているファイルを移動させます:

FROM nodered/node-red

# Copy package.json to the WORKDIR so npm builds all
# of your added nodes modules for Node-RED
COPY package.json .
RUN npm install --unsafe-perm --no-update-notifier --no-fund --only=production

# Copy _your_ Node-RED project files into place
# NOTE: This will only work if you DO NOT later mount /data as an external volume.
#       If you need to use an external volume for persistence then
#       copy your settings and flows files to that volume instead.
COPY settings.js /data/settings.js
COPY flows_cred.json /data/flows_cred.json
COPY flows.json /data/flows.json

# You should add extra nodes via your package.json file but you can also add them here:
#WORKDIR /usr/src/node-red
#RUN npm install node-red-node-smooth

Note: the package.json file must contain a start option within the script section. For example the default container is like this:

    "scripts": {
        "start": "node $NODE_OPTIONS node_modules/node-red/red.js $FLOWS",
        ...

Dockerfile order and build speed

必要ない限り、COPY package... npm install...ステップを早い段階でおこなうことが推奨されます。なぜならば、Node-REDを使う際に頻繁にflows.jsonを変更しますが、package.jsonはプロジェクトに含まれるモジュールを変更したときのみ変更するためです。また、package.jsonを変更したときに必要となるnpm installステップはしばしば時間を要するため、時間がかかり、一般的に変更のないステップをDockerファイル内の早い段階でおこない、ビルドイメージを再利用できるようにして、以降の全体のビルドを高速化することは推奨されます。

資格情報、シークレットおよび環境変数

当然ですが、資格情報をどこかにハードコードすることは望まないため、Node-REDプロジェクトに資格情報が必要な場合、上述のDockerファイルを利用してsettings.js内に以下の項目を持たせてください。

module.exports = {
  credentialSecret: process.env.NODE_RED_CREDENTIAL_SECRET // 正確にこれを書き足してください
}

…そして、実行しているDocker内で、runコマンドに環境変数を追加してください…

docker run -e "NODE_RED_CREDENTIAL_SECRET=your_secret_goes_here"

ビルドおよび実行

通常通りDockerファイルを_ビルド_します:

docker build -t your-image-name:your-tag .

作業しているローカルディレクトリでの変更だけをすぐに開発目的でローカルで 実行 するためには、cdを使ってプロジェクトのディレクトリに移動し、以下のように実行します:

docker run --rm -e "NODE_RED_CREDENTIAL_SECRET=your_secret_goes_here" -p 1880:1880 -v `pwd`:/data --name a-container-name your-image-name

起動

環境変数はNode-RED実行環境を設定するコンテナに引き渡すことが可能です。

フロー設定ファイルは、 デフォルトでは‘flows.json’となっている環境変数(FLOWS)を使うことで設定します。 以下のコマンドラインフラグによって実行時に変更することができます。

docker run -it -p 1880:1880 -v node_red_data:/data -e FLOWS=my_flows.json nodered/node-red

Note: -e FLOWS=""を指定した場合、 settings.jsファイル内のflowFileプロパティを経由してフローファイルに設定されます。

その他有用な環境変数は以下のとおりです

  • -e NODE_RED_ENABLE_SAFE_MODE=false # trueに設定することでセーフ(実行されない)モードでNode-REDを起動します
  • -e NODE_RED_ENABLE_PROJECTS=false # trueに設定することでプロジェクト機能を有効にしてNode-REDを起動します

Node.jsの実行時引数は環境変数(NODE_OPTIONS)を使うことでコンテナに引き渡すことができます。 例えば、Node.jsガーベージコレクタを使うことでヒープサイズの修正をおこなうためには 以下のコマンドを使用します。

docker run -it -p 1880:1880 -v node_red_data:/data -e NODE_OPTIONS="--max_old_space_size=128" nodered/node-red

ヘッドレスで実行する

ヘッドレス(つまりバックグラウンド)で実行するには、前述のほとんどのコマンドで-it-dに置換するだけであり、 以下の例のようになります:

docker run -d -p 1880:1880 -v node_red_data:/data --name mynodered nodered/node-red

コンテナシェル

ヘッドレスで実行した場合、コンテナにアクセスし直すためには以下のコマンドを利用します。

$ docker exec -it mynodered /bin/bash
bash-4.4$

コンテナ内のコマンドラインを表示します - 実行したいnpm installコマンドを実行できます

  • bash-4.4$ npm install node-red-dashboard
    bash-4.4$ exit
    $ docker stop mynodered
    $ docker start mynodered
    

そして、ブラウザページを更新することでパレットに新しく追加したノードが現れるはずです。

複数インスタンス

以下のように実行すると、

docker run -d -p 1880 nodered/node-red

マシンのローカルインスタンスを作成できます。注意: 特定の命名はしていません。

このコンテナはID番号を持ち、ランダムなポート番号で実行されます… どのポートなのかを知るには、docker psを実行します

$ docker ps
CONTAINER ID  IMAGE             COMMAND                 CREATED         STATUS        PORTS                    NAMES
860258cab092  nodered/node-red  "npm start -- --user…"  10 seconds ago  Up 9 seconds  0.0.0.0:32768->1880/tcp  dazzling_euler

ここで判明したTCPポートでホストマシンをブラウザで指定することができ、 つまり上述の例ではhttp://{host ip}:32768でブラウジングします。

コンテナのリンク

Docker user-defined bridgesを使用することでDocker実行環境の「内部に」コンテナをリンクすることができます。

ブリッジを使う前に作成する必要があります。以下のコマンドは iot と呼ばれる新たなブリッジを作成します。

docker network create iot

連携する必要のある全てのコンテナは、–networkというコマンドラインオプションを利用して同一ブリッジに追加する必要があります。

docker run -itd -e NO_AUTHENTICATION=1 --network iot --name mybroker eclipse-mosquitto

(望まない限り、ポート1883をグローバルに公開する必要はありません。後で魔法をかけます。)

そしてnodered dockerを実行し、同じブリッジに追加します

docker run -itd -p 1880:1880 --network iot --name mynodered nodered/node-red

同一ユーザー定義ブリッジ上のコンテナは、ブリッジによって提供される名前解決を利用し、ターゲットホスト名としてコンテナ名( –nameオプションを利用して特定される)を利用できます。

上述の例では、mybrokerというホスト名を使ってNode-REDアプリケーションからブローカーに到達できます。

以下にMQTTノードがブローカーに接続するシンプルなフローを示します

    [{"id":"c51cbf73.d90738","type":"mqtt in","z":"3fa278ec.8cbaf","name":"","topic":"test","broker":"5673f1d5.dd5f1","x":290,"y":240,"wires":[["7781c73.639b8b8"]]},{"id":"7008d6ef.b6ee38","type":"mqtt out","z":"3fa278ec.8cbaf","name":"","topic":"test","qos":"","retain":"","broker":"5673f1d5.dd5f1","x":517,"y":131,"wires":[]},{"id":"ef5b970c.7c864","type":"inject","z":"3fa278ec.8cbaf","name":"","repeat":"","crontab":"","once":false,"topic":"","payload":"","payloadType":"date","x":290,"y":153,"wires":[["7008d6ef.b6ee38"]]},{"id":"7781c73.639b8b8","type":"debug","z":"3fa278ec.8cbaf","name":"","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":505,"y":257,"wires":[]},{"id":"5673f1d5.dd5f1","type":"mqtt-broker","z":"","name":"","broker":"mybroker","port":"1883","clientid":"","usetls":false,"compatmode":false,"keepalive":"15","cleansession":true,"birthTopic":"","birthQos":"0","birthRetain":"false","birthPayload":"","closeTopic":"","closeRetain":"false","closePayload":"","willTopic":"","willQos":"0","willRetain":"false","willPayload":""}]

この方法は内部ブローカーをDockerホスト外に公開しません - 自身のコンピュータ以外の他のシステムにブローカーを利用させたい場合、-p 1883:1883などをブローカーに追加してコマンドを実行することができます。

Raspberry PI - ネイティブGPIOサポート

| v1.0 - 緊急: Raspberry PIのネイティブGPIOサポートは廃止されました | | — | ネイティブGPIOの代替はnode-red-node-pi-gpiodです。

ネイティブGPIOサポートの欠点は以下のとおりです:

  • Dockerコンテナは、gpioをコントロールしたい同じDockerノード/ホストにデプロイする必要があります
  • Dockerノード/ホストの/dev/memにアクセスします
  • privileged=trueはdocker stackコマンドではサポートされていません

node-red-node-pi-gpiodはこれらの全ての欠点を解消します。node-red-node-pi-gpiodは単一のNode-REDコンテナから複数のRaspberry Piのgpioと情報交換すること、そして複数のコンテナが同じRaspberry Piの異なるgpioにアクセスすることが可能にします。

node-red-node-pi-gpiodへのクイック移行手順

  1. Node-REDパレットを通してnode-red-node-pi-gpiodをインストールします
  2. ホストのPaspberry PiにPiGPIOd daemonをインストールして実行します
  3. pi gpiodノードによって全てのネイティブGPIOノードを置換します
  4. PiGPIOd daemonに接続するようにpi gpioノードを設定します。ほとんどのホストマシンはIPアドレス172.17.0.1 ポート番号8888がありますが、常ではありません。確認にはdocker exec -it mynodered ip route show default | awk '/default/ {print $3}'を利用できます。

Note: 必要な場合、ホスト上ではなくそれ自身のコンテナでgpiodを実行するgpiod projectが存在します。

シリアルポート - ダイアルアウト - グループへの追加

ホストシリアルポートへアクセスするためには、dialoutグループにコンテナを追加する必要があります。起動コマンドに--group-add dialoutを追加することで有効できます。例は以下の通りです。

docker run -it -p 1880:1880 -v node_red_data:/data --group-add dialout --name mynodered nodered/node-red

よくある問題とヒント

ここではユーザが報告した一般的な問題と解決策の一覧を示します。

ユーザ権限のエラー

権限に関する詳細な情報については wikiを参照してください。

権限拒否エラーを確認した場合、ファイルを開くかホストデバイスにアクセスし、ルートユーザとしてコンテナを起動してみてください。

docker run -it -p 1880:1880 -v node_red_data:/data --name mynodered -u node-red:dialout nodered/node-red

リファレンス:

https://github.com/node-red/node-red-docker/issues/15

https://github.com/node-red/node-red-docker/issues/8

ホストデバイスにアクセスする

コンテナ内のホストからデバイスにアクセスしたい、例えばシリアルポートの場合、以下のコマンドラインフラグを使ってアクセスします。

docker run -it -p 1880:1880 -v node_red_data:/data --name mynodered --device=/dev/ttyACM0 nodered/node-red

リファレンス: https://github.com/node-red/node-red/issues/15

タイムゾーンを設定する

デフォルトのタイムゾーンを変更したい場合、相対タイムゾーンを用いたTZ環境変数を使用します。

docker run -it -p 1880:1880 -v node_red_data:/data --name mynodered -e TZ=America/New_York nodered/node-red

or within a docker-compose file

  node-red:
    environment:
      - TZ=America/New_York

リファレンス: https://groups.google.com/forum/#!topic/node-red/ieo5IVFAo2o