結論

Node-RED(ノードレッド)は、四角い「ノード」を線でつないで処理の流れ(フロー)を作る、Node.js 製のローコード開発ツールです。センサーや MQTT のデータを集める、Web API を受けて返す、決まった時刻に処理を動かす、といった「つなぐ仕事」を少ないコードで作れます。

この記事でわかること

  • npm で入れて5分で最初の出力を出す手順と、その起動ログ
  • inject→function→debug、HTTP の受け口、MQTT を動かした実物
  • 認証が無い初期状態の危うさ、エラー原文12件、n8n との使い分け

2026年10月29日更新|Node-RED 5.0.9・Node.js 22.23.4・Chromium で実行確認

Node-RED では、ブラウザの画面(エディター)でフローを描き、「デプロイ」を押すと、裏で動く Node.js のプログラム(ランタイム)がそのフローを実行します。流れるデータは msg という1つの JavaScript のオブジェクトです。

flowchart TD
    E[ブラウザのエディター] -->|デプロイ| R[Node-RED ランタイム]
    R --> S[(flows.json に保存)]
    R --> A[受け取る<br>inject / http in / mqtt in]
    A -->|msg| B[加工・分岐<br>function / switch / change]
    B -->|msg| C[出す<br>debug / http response / mqtt out]

よく調べられることの答えを先にまとめます。

知りたいこと 答え 詳しい節
Node-REDとは ノードを線でつないでフローを作るローコードツール。IBM 発、今は OpenJS Foundation のプロジェクト Node-REDとは
Node-RED 使い方(最初の一歩) npm で入れて起動→ブラウザで開く→inject・debug を置く→デプロイ 5分で動かす
Node-RED インストール npm・Docker・Raspberry Pi 用スクリプト。5.x は Node.js 22.9 以上 インストール方法の選び方
Node-REDは無料? 無料。Apache License 2.0 で商用にも使える Node-REDとは
Web API を作れる? http in と http response のノードで作れる HTTPの受け口
MQTT をつなぐには mqtt in・mqtt out と、ブローカーの設定ノード MQTTを送受信する
パスワードを付けるには settings.js の adminAuth。http in は別に httpNodeAuth セキュリティ設定
n8n との違い Node-RED は機器・プロトコル寄りで軽い。n8n は SaaS 連携と実行履歴が強い n8nとの違い

確認環境:Linux(x86_64、2 CPU・メモリ 8GB、ほかの作業と共用)の上で、Node.js 22.23.4 を使い、Node-RED 5.0.9 を作業フォルダに npm install で入れました(グローバルには入れていません)。ユーザーディレクトリ(設定とフローの置き場所)も作業フォルダに置き、エディターは 127.0.0.1 だけで待ち受けさせ、使用状況の送信(telemetry)とパレットからの追加インストールは切っています。MQTT は手元に Node.js 製のブローカー aedes 1.2.0 を 127.0.0.1 で立てて送受信しました。フローの反映は Admin API(エディターが内部で使う HTTP の API)と、Chromium(Playwright から操作)で開いたエディターの両方で確かめています。外部のサービスにつなぐノード(メール・クラウド・SNS など)は動かしていません。Docker・Raspberry Pi・Windows の手順、Node.js の版の対応は Node-RED 公式ドキュメントで確かめました。ログの先頭の日付は省き、時刻は UTC のまま載せています(確認日 2026年10月29日)。

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「Node-REDとは?使い方を実行ログで解説|HTTP・MQTT・n8n比較」

Node-REDとは(読み方・できること・仕組み)

この節では、Node-RED が何をする道具で、どんな仕事に向いているかが分かります。

Node-RED は、公式サイトで「フローベースのプログラミングツール」と説明されている、ノードをつないで処理を組み立てる開発ツールです。読み方は「ノードレッド」。2013年に IBM の Emerging Technology Services のチームで、MQTT のトピックどうしの対応を目で見て組み替える道具として始まり、同じ年の9月にオープンソースになりました。2016年に JS Foundation の創設プロジェクトの1つになり、2019年からは OpenJS Foundation(Node.js と同じ財団)のプロジェクトです。

ライセンスは Apache License 2.0 で、手元に入った node-red の package.json にも "license": "Apache-2.0" と書かれていました。本体は無料で、商用の仕組みに組み込んで使えます。追加ノード(コミュニティが作ったノード)は、それぞれのライセンスを確かめます。

1機器とつなぐ

MQTT・TCP・UDP・シリアル・WebSocket のノードで、センサーや工場の機器からデータを受け取り、加工して保存・通知する。Raspberry Pi でもよく動かされる。

2小さな Web API を作る

http in で URL を受け、function で加工し、http response で JSON を返す。社内向けの中継やモック(試験用の偽物の API)に向く。

3決まった時刻に動かす

inject ノードの繰り返し設定で、5秒ごと・毎朝などの定期処理を作る。cron を書かずに画面で組める。

4データの形を変える

CSV・JSON・XML・YAML・HTML のパーサーノード、split・join・sort・batch で、受け取ったデータを並べ替えたりまとめたりする。

手元の 5.0.9 で、パレット(ノードの一覧)に並んだ標準ノードは43個でした。外部のサービス専用のノード(クラウドのデータベース・チャットなど)は標準には入っておらず、必要なものを npm の追加ノードとして入れます。この点が、最初から数百のサービス用ノードを持つ n8n や Zapier との大きな違いです。

5分で動かすNode-RED:インストールから最初の出力まで

この節では、Node-RED を入れて、ブラウザでエディターを開くまでの最短の手順と、そのときのログが分かります。

Node.js 22.9 以上があれば、作業フォルダで npm install node-red を打ち、npx node-red で起動できます。公式ドキュメントは sudo npm install -g node-red(グローバル)を案内していますが、試すだけなら作業フォルダに入れるほうが、消すときにフォルダごと消せて後始末が楽です。

1

Node.js の版を確かめる

node -v が v22.9 以上か見る。5.x は Node.js 22.9 以上が要り、公式は 24 を推奨している。足りなければ先に Node.js を更新する。

10秒

2

作業フォルダに入れる

npm init -y のあと npm install node-red。手元では276個のパッケージが入り、25秒、node_modules は112MB だった。

30秒前後

3

127.0.0.1 だけで起動する

npx node-red -u ./data -D uiHost=127.0.0.1。-u で設定とフローの置き場所を決め、-D で待ち受けアドレスを自分の PC だけに絞る。

1〜4秒

4

ブラウザで開く

ログに出た Server now running at http://127.0.0.1:1880/ を開く。初回は Node-RED 5.0 の新機能を紹介するツアーが出るので、右上の × で閉じる。

初回だけ

5

inject と debug をつないでデプロイ

左のパレットから inject と debug を置いて線でつなぎ、右上の「デプロイ」。inject の左の四角を押すと、右の「デバッグメッセージ」に時刻の数字が出る。

1分

node -v                       # v22.23.4
mkdir node-red-work && cd node-red-work
npm init -y
npm install node-red@5.0.9    # added 276 packages in 25s
npx node-red -u ./data -p 1880 -D uiHost=127.0.0.1 -D telemetry.enabled=false

起動したときのログです(ユーザーディレクトリは別のパスにしています)。

[info] Welcome to Node-RED
[info] Node-RED version: v5.0.9
[info] Node.js  version: v22.23.4
[info] Linux 6.18.44-fc-v185 x64 LE
[info] Loading palette nodes
[info] Settings file  : /path/to/data/settings.js
[info] Context store  : 'default' [module=memory]
[info] User directory : /path/to/data
[warn] Projects disabled : editorTheme.projects.enabled=false
[info] Flows file     : /path/to/data/flows.json
[info] Creating new flow file
[warn]
---------------------------------------------------------------------
Your flow credentials file is encrypted using a system-generated key.
...
You should set your own key using the 'credentialSecret' option in
your settings file.
---------------------------------------------------------------------
[info] Server now running at http://127.0.0.1:1880/
[warn] Encrypted credentials not found
[info] Starting flows
[info] Started flows

ログから読み取れることです。

  • Settings file・User directory:初回の起動で、ユーザーディレクトリに settings.js の雛形がコピーされます。-u を付けないと、置き場所はホームの ~/.node-red です。
  • credentialSecret の警告:パスワードなどの資格情報を暗号化する鍵を自動で作った、という知らせです。鍵は .config.runtime.json に保存されます。後の「セキュリティ設定」の節で自分の鍵に変えます。
  • Encrypted credentials not found:まだ資格情報が1つも無いという意味で、初回はエラーではありません。
  • Projects disabled:Git でフローを管理する「プロジェクト機能」が既定で無効という知らせです。

-D uiHost=127.0.0.1 を付けずに起動すると、雛形の settings.js では uiHost がコメントになっているため、すべてのネットワークの出入口で待ち受けます。同じネットワークの他の PC からもエディターを開ける状態になるので、試すときは付けておくのが安全です。手元で ss -ltnp を見ると、付けたときは 127.0.0.1:1880 だけで待ち受けていました。

Node-REDの画面の見方と基本用語(フロー・ノード・msg・デプロイ)

この節では、エディターの各部分の名前と、Node-RED を使うときに出てくる言葉の意味が分かります。

エディターは、左にパレット、真ん中にワークスペース(フローを描く場所)、右にサイドバーがあり、右上の「デプロイ」で描いたフローが動き出します。Chromium の言語を日本語にして開くと、メニューも日本語で表示されました(「エクスプローラ」「パレット」「デバッグメッセージ」「デプロイ」など)。

用語 意味 画面のどこ
ノード 1つの仕事をする部品。入口(左の丸)と出口(右の丸)がある 左のパレット
フロー ノードを線でつないだ1つの流れ。タブ1枚が1つのフロー 上のタブ
msg ノードの間を流れるオブジェクト。中身の多くは msg.payload に入る debug ノードで見る
デプロイ 描いたフローをランタイムに送って動かすこと。保存も兼ねる 右上のボタン
設定ノード MQTT のブローカーなど、複数のノードで共有する接続設定 エクスプローラの「グローバル設定ノード」
コンテキスト ノード・フロー・全体で値を覚えておく場所 サイドバーのコンテキストデータ
サブフロー いくつかのノードを1つのノードにまとめたもの メニューの「サブフロー」

「ノード」という言葉は、場面によって指すものが違います。検索で別の意味の記事が出てきたときの見分けに使ってください。

場面 「ノード」が指すもの
Node-RED・n8n・Dify フローの中の部品1つ(inject、HTTP Request など)
Node.js ノードではなく実行環境の名前。node コマンド
ネットワーク・Kubernetes つながっている機器・サーバー1台
データ構造(木・グラフ) 点(節点)1つ。HTML の DOM の要素もノードと呼ぶ

デプロイのボタンの右の▼では、反映のしかたを「全て」「変更したフロー」「変更したノード」から選べます。手元で「変更したフロー」にすると、ログは Stopping modified flows → Started modified flows になり、変えていないフローは止まらずに動き続けました。

最初のフローを作る:inject→function→debug

この節では、Node-RED の基本の形である「きっかけ→加工→表示」のフローを作り、動いた結果が分かります。

inject(きっかけ)で時刻を送り、function(加工)で形を整え、debug(表示)で結果を見るのが、Node-RED の最初の1本です。手元では次のように設定しました。

  • inject:名前「5秒ごと」、msg.payload に「日時」、繰り返し「5秒ごと」、デプロイ直後に1回送る。
  • function:名前「時刻を整える」。下のコードを書く。
  • debug:名前「結果」。デバッグメッセージに加えて、ログ(コンソール)にも出す。
// function ノード「時刻を整える」
const d = new Date(msg.payload);   // inject が送るのは 1970年からのミリ秒
msg.payload = {
  iso: d.toISOString(),
  hour: d.getUTCHours(),
  even: d.getUTCSeconds() % 2 === 0
};
return msg;                        // 次のノードへ渡す

デプロイすると、5秒ごとにログへ次の行が出ました(ISO の日付部分は省いています)。

23:59:14 - [info] Started flows
23:59:14 - [info] [debug:結果]
{ iso: '…T23:59:14.580Z', hour: 23, even: true }
23:59:19 - [info] [debug:結果]
{ iso: '…T23:59:19.587Z', hour: 23, even: false }

エディターの右の「デバッグメッセージ」には、ノード: 結果・msg.payload : Object の見出しの下に同じ中身が出ます。inject ノードの左の四角を押すと、画面の上に「inject処理を実行しました: 5秒ごと」と出て、すぐに1件増えました。inject の名前の右の小さな「¹」は、「デプロイ直後に1回送る」が有効という印です。

function で return msg

次のノードへ msg を渡す

出口が2つなら return [msg, null] で1番目だけ

配列で返すと、出口ごとに別の msg を送れる

function で return null

何も送らずにそこで止める

条件に合わないデータを捨てるときに使う

return を書き忘れると、次のノードに何も届かない

functionノードの書き方:msg・分岐・状態(context)

この節では、function ノードで使える主な書き方と、値を覚えておく「コンテキスト」の動きが分かります。

function ノードの中は普通の JavaScript で、msg を受け取って msg を返します。そのほかに、ログを出す node.warn、ノードの下に状態を出す node.status、値を覚える flow.get・flow.set がよく使われます。呼ばれた回数を数え、3の倍数のときだけ2番目の出口へ送るフローを作りました。

// function ノード「数えて振り分け」(出口は2つ)
let n = flow.get('count') || 0;
n += 1;
flow.set('count', n);                       // フローのコンテキストに保存
node.status({ fill: 'green', shape: 'dot', text: `${n}回目` });
msg.payload = { count: n };
if (n % 3 === 0) {
  node.warn(`${n}回目は3の倍数`);           // ログとデバッグに警告を出す
  return [null, msg];                       // 2番目の出口へ
}
return [msg, null];                         // 1番目の出口へ

2番目の出口の先に、payload.fizz に true を入れる change ノードを置き、どちらも http response につなぎました。4回呼んだ結果とログです。

$ curl http://127.0.0.1:18191/count   (4回)
{"count":1}
{"count":2}
{"count":3,"fizz":true}
{"count":4}

00:08:04 - [warn] [function:数えて振り分け] 3回目は3の倍数

このとき、Admin API でフローのコンテキストを読むと {"memory":{"count":{"msg":"4","format":"number"}}} でした。ところが、Node-RED を再起動してからもう一度呼ぶと {"count":1} に戻りました。既定のコンテキストはメモリだけに置かれ、再起動で消えます。残したいときは settings.js の contextStorage で localfilesystem を指定します(雛形の settings.js にコメントで例があります)。

書き方 何をするか 手元での結果
return msg 次のノードへ渡す debug に出た
return [null, msg] 2番目の出口だけへ渡す 3回目だけ fizz が付いた
node.warn() 警告をログとデバッグに出す [warn] [function:数えて振り分け]
node.error(文, msg) エラーにして catch ノードへ回す catch が受け取った(次の節)
flow.set() フロー内で値を覚える 再起動で消えた(既定のメモリ)

HTTPの受け口を作る:http in→http response

この節では、Node-RED で Web API を作る方法と、分岐・エラーの返し方が、実際の応答で分かります。

http in ノードで URL とメソッドを決め、http response ノードで応答を返すと、Node-RED が小さな Web サーバーになります。エディターと同じポートで待ち受けます。GET /hello を作り、クエリの name を使ってあいさつを返しました。

// function ノード「あいさつ」
const name = msg.req.query.name || 'ゲスト';
msg.payload = { message: `こんにちは、${name}さん` };
return msg;
$ curl -i "http://127.0.0.1:18191/hello?name=%E5%B1%B1%E7%94%B0"
HTTP/1.1 200 OK
X-Content-Type-Options: nosniff
Content-Type: application/json; charset=utf-8
Content-Length: 44
ETag: W/"2c-cE+aRNTL+ZjRhsc+SOwuuOOyeFA"
Connection: keep-alive
Keep-Alive: timeout=5

{"message":"こんにちは、山田さん"}

msg.payload にオブジェクトを入れると、http response が JSON にして Content-Type: application/json を付けました。次に、POST /api/temp で温度を受け取り、switch ノードで30度以上かどうかを分けて、change ノードで level を足して返すフローです。

$ curl -X POST -H 'Content-Type: application/json' -d '{"temp":32.5,"line":"line1"}' http://127.0.0.1:18191/api/temp
{"temp":32.5,"line":"line1","level":"warning"}

$ curl -X POST -H 'Content-Type: application/json' -d '{"temp":25}' http://127.0.0.1:18191/api/temp
{"temp":25,"level":"ok"}

$ curl -X POST -d 'temp=40' http://127.0.0.1:18191/api/temp
{"temp":"40","level":"warning"}

フォーム形式で送った3つ目は、temp が文字列の "40" のまま届きましたが、switch の「30以上(数値)」では数値として比べられ、warning になりました。JSON・フォームのどちらでも受け取れる反面、型がそろわないまま後ろへ流れるので、保存の前に Number() でそろえると安全です。

エラーを catch ノードで受けて 400 を返す

受け取った文字列を JSON.parse する function を置き、失敗したら catch ノードで拾って 400 を返すようにしました。catch の先の function で msg.statusCode = 400 を入れると、http response がその番号で返します。

$ curl "http://127.0.0.1:18191/boom?v=%7B%22a%22%3A1%7D"
{"a":1}

$ curl -i "http://127.0.0.1:18191/boom?v=%7Ba"
HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=utf-8

{"error":"SyntaxError: Expected property name or '}' in JSON at position 1 (line 1 column 2)","node":"わざと失敗"}

http response まで msg が届かないと、応答は返りません。function で return null するだけの GET /drop を作って呼ぶと、30秒待っても応答が無く、curl はタイムアウト(exit 28)で終わりました。http in を使うフローでは、失敗の道にも必ず http response を置くのが決まりです。

1

catch ノード

指定したノード(または同じタブの全ノード)のエラーを受け取る。msg.error に文言と発生元が入る。

400・500 を返す道を作る

2

node.error(文, msg)

function の中で、自分でエラーにする。msg を一緒に渡すと catch に届く。

入力の検査に使う

3

status ノード

ノードの状態表示(接続・切断など)が変わったときに msg を出す。

MQTT の切断を通知する

4

complete ノード

指定したノードが処理を終えたときに msg を出す。

後片付け・記録

Webhook を受ける側の作り方(署名の検証・リトライ・二重受信の防ぎ方)は、関連記事「Webhookとは?実装までわかる|署名検証・リトライ・冪等性を実行ログで解説」で扱っています。Node-RED の http in で Webhook を受けるときも、同じ考え方がそのまま当てはまります。

MQTTをNode-REDで送受信する(手元のブローカー)

この節では、Node-RED の MQTT ノードの設定と、ブローカーが止まったときの動きが分かります。

MQTT は、ブローカー(中継役のサーバー)を通して、トピック(宛先の名前)ごとにメッセージを配る仕組みで、Node-RED が生まれたきっかけでもあります。手元に Node.js 製のブローカー aedes を 127.0.0.1:18831 で立て、Node-RED から送信と受信の両方を行いました。

  1. mqtt-broker の設定ノード:サーバー 127.0.0.1、ポート 18831、クライアント ID nodered-t191、MQTT 3.1.1。
  2. 送る側:前の節の switch の「30度以上」の出口に mqtt out をつなぎ、トピック factory/line1/alert、QoS 1 で送る。
  3. 受ける側:別のタブに mqtt in を置き、トピック factory/+/alert(+ は1階層の何でも)、出力は「自動判定」。
--- Node-RED のログ
23:59:51 - [info] [mqtt-broker:手元のブローカー] Connected to broker: nodered-t191@mqtt://127.0.0.1:18831
00:00:00 - [info] [debug:MQTT受信]
{
  topic: 'factory/line1/alert',
  payload: { temp: 32.5, line: 'line1' },
  qos: 1,
  retain: false,
  ...
}

--- ブローカー(aedes)のログ
client connected nodered-t191
publish factory/line1/alert {"temp":32.5,"line":"line1"}
publish factory/line1/alert {"temp":"40"}

出力を「自動判定」にした mqtt in は、JSON の文字列をオブジェクトにして payload に入れました。届いたのは level が付く前の中身です。switch の出口から change と mqtt out の2本に分けたため、mqtt out には change を通る前の msg が渡ったからです。線を分けたときは、どの時点の msg が届くかを debug で確かめます。

ブローカーを止めたときの動き

ブローカーのプロセスを止めると、Node-RED は Disconnected from broker を1行出し、MQTT ノードの下の表示が切断に変わりました。止まっている間に送った1件は、ブローカーを起こし直したあともブローカーに届いた記録がありませんでした(QoS 1・クリーンセッションの設定)。再接続は、ブローカーを起こしてから十数秒後でした。settings.js の mqttReconnectTime の既定値は 15000(ミリ秒)です。

00:01:13 - [info] [mqtt-broker:手元のブローカー] Disconnected from broker: nodered-t191@mqtt://127.0.0.1:18831
00:01:58 - [info] [mqtt-broker:手元のブローカー] Connected to broker: nodered-t191@mqtt://127.0.0.1:18831

切断中のデータを落とせない用途では、status ノードで切断を検知して別の場所に溜める、ブローカー側の永続セッションを使う、などの手当てが要ります。QoS・Retain・Will の意味と、パケットの中身は関連記事「MQTTとは|仕組み・QoS・Retain・WillをPythonとパケットで解説」で扱っています。この記事は Node-RED のノードの使い方に絞り、MQTT そのものの仕組みはそちらに任せます。

フローのJSONの中身と書き出し・読み込み・Git管理

この節では、Node-RED のフローがどんなファイルで保存され、どう持ち運ぶかが分かります。

フローは、ユーザーディレクトリの flows.json に、ノード1つを1つのオブジェクトとする JSON の配列で保存されます。最初のフローの function ノードは、次の形でした。

{
  "id": "fn1",
  "type": "function",
  "z": "tab1",
  "name": "時刻を整える",
  "func": "const d = new Date(msg.payload);\nmsg.payload = { ... };\nreturn msg;",
  "outputs": 1,
  "x": 300,
  "y": 80,
  "wires": [["dbg1"]]
}
項目 意味
id ノードの ID。線の行き先はこの ID で書かれる
type ノードの種類(inject・function・http in など)
z どのタブ(フロー)に置かれているか
wires 出口ごとのつなぎ先の配列。出口2つなら [["a"],["b"]]
x・y 画面上の位置。動かすだけで差分が出る

デプロイのたびに、ユーザーディレクトリの中身は次のように変わりました。

flows.json              フロー本体(flowFilePretty: true で整形して保存)
.flows.json.backup      1つ前のデプロイの flows.json
flows_cred.json         資格情報(パスワード等)。暗号化されて {"$":"..."} の形
.config.runtime.json    自動で作った暗号化の鍵(credentialSecret を決めると消える)
.config.users.json      エディターのユーザー設定
settings.js             設定ファイル
  • 書き出し:エディターでノードを選び、右上のメニュー(三本線)→「書き出し」。JSON をクリップボードに写すか、ファイルとして保存します。
  • 読み込み:メニュー →「読み込み」で JSON を貼ります。入っていないノードを含む JSON を読み込むと、次の「よくあるエラー」の節の「missing types」になります。
  • Git で管理する:flows.json と settings.js を Git に入れ、flows_cred.json は鍵(credentialSecret)と分けて扱います。プロジェクト機能(editorTheme.projects.enabled)を有効にすると、エディターからコミットできます。
  • API で入れる:POST /flows に JSON を送るとデプロイになります。手元では Node-RED-Deployment-Type ヘッダーを付けずに送ると全体(full)、flows を付けると変更したフローだけが再起動しました。

Node-REDのセキュリティ設定:adminAuth・httpNodeAuth・待ち受けアドレス

この節では、初期状態の Node-RED に何が足りないかと、最低限入れる設定が、実際の応答で分かります。

初期状態の Node-RED のエディターと Admin API には、パスワードがありません。公式ドキュメントも「By default, the Node-RED editor is not secured」と書き、信頼できるネットワークでだけ使うよう求めています。手元で何も設定せずに試すと、次のとおりでした。

要求 設定なし adminAuth あり httpNodeAuth も追加
GET /flows(フローを読む) 200 401 401
POST /flows(フローを書き換える) 204 401 401
GET /diagnostics(環境の情報) 200 401 401
GET /hello(自分で作った http in) 200 200 401(Basic 認証で 200)

設定なしでは、誰でもフローを読めて、書き換えて動かせます。エディターには OS のコマンドを動かす exec ノードもあるため、エディターに入れる人は、Node-RED を動かしているユーザーの権限で何でもできると考えます。/diagnostics も、Node.js・OS の版やメモリの量を返していました。

公開の前にやってはいけないこと

NGuiHost を空けたまま、ルーターやクラウドのポート1880を開けて外から見えるようにする
→
代わりにuiHost: "127.0.0.1" にし、外からは adminAuth を入れたうえで HTTPS のリバースプロキシか VPN 越しに入る

見分ける問い:「同じネットワークの他人がエディターを開けるか」

adminAuth でエディターにパスワードを付ける

パスワードはそのまま書かず、bcrypt のハッシュにします。Node-RED に付いているコマンドで作れます。

$ npx node-red admin hash-pw
Password: (入力は表示されない)
$2y$08$gUlrroYJsa/KPBmrgpt9beqOjObMA.zU3mBZ0To0OZQ81SThWavTG
// settings.js(module.exports の中)
uiHost: "127.0.0.1",
adminAuth: {
    type: "credentials",
    users: [{
        username: "admin",
        password: "$2y$08$gUlr...(hash-pw の出力)",
        permissions: "*"          // 読むだけの人は "read"
    }]
},
httpNodeAuth: { user: "api", pass: "$2y$08$...(hash-pw の出力)" },
credentialSecret: process.env.NODE_RED_CREDENTIAL_SECRET,

再起動すると、エディターを開いたときにログインの画面が出るようになり、Admin API は次のように応えました。

$ curl -i http://127.0.0.1:18191/flows
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="Users"
Content-Length: 12

Unauthorized

$ curl -X POST -d 'client_id=node-red-admin&grant_type=password&scope=*&username=admin&password=(違う値)' http://127.0.0.1:18191/auth/token
{"error":"invalid_grant","error_description":"Invalid resource owner credentials"}   ← 403

$ curl -X POST -d '...(正しい値)' http://127.0.0.1:18191/auth/token
{"access_token":"(省略)","expires_in":604800,"token_type":"Bearer"}

expires_in の 604800 秒は7日で、公式ドキュメントの「トークンは作られてから7日で切れる」と一致しました。adminAuth.sessionExpiryTime(秒)で変えられます。

http in は adminAuth では守られない

表のとおり、adminAuth を入れても、自分で作った http in の URL は誰でも呼べるままでした。http in にも認証を付けるには httpNodeAuth を足します。足したあとは WWW-Authenticate: Basic realm="Authorization Required" の 401 になり、curl -u api:パスワード で 200 が返りました。URL ごとに認証を変えたいときは、http in の後ろで msg.req.headers を確かめる処理を自分で書きます。

credentialSecret を自分で決める

起動ログの警告どおり、決めないと鍵は自動で作られて .config.runtime.json の _credentialSecret に保存されます。上のように環境変数から読む形にして再起動し、デプロイすると、.config.runtime.json から鍵の行が消え、instanceId だけになりました。鍵を決めておけば、flows_cred.json を別のマシンに移しても、同じ鍵で読めます。

  • 1uiHost を 127.0.0.1 にした外から使うならリバースプロキシか VPN を前に置く
  • 2adminAuth を入れ、GET /flows が 401 になるのを確かめた設定の書き損じがあると、認証なしのまま起動する
  • 3http in の URL の守り方を決めたhttpNodeAuth か、自前の検査
  • 4credentialSecret を自分で決め、Git に入れない場所に置いた環境変数などから読む
  • 5パレットからの追加インストールを使うか決めた使わないなら externalModules.palette.allowInstall: false
  • 6HTTPS にした(https の設定かプロキシ)パスワードやトークンを平文で流さない

Node-REDのインストール方法の選び方(npm・Docker・Raspberry Pi)と版

この節では、Node-RED の入れ方ごとの違いと、Node.js の版の選び方が分かります。

Node-RED 5.x は Node.js 22.9 以上が必要で、公式は Node.js 24 を推奨しています。4.x は Node.js 18 以上です。5.0.0 の変更履歴にも「Node-RED now requires Node 22.9 or later」と書かれています。手元の 5.0.9 の起動処理は、版が足りないと Unsupported version of Node.js と Node-RED requires Node.js v22.9 or later を表示して止まるように書かれていました。

入れ方 コマンド(公式) データの置き場所 向く場面
npm(グローバル) sudo npm install -g node-red(Windows は sudo なし) ~/.node-red 手元の PC で長く使う
npm(作業フォルダ) npm install node-red→npx node-red -u ./data -u で決めた場所 試す・版を固定する
Docker docker run -it -p 1880:1880 -v node_red_data:/data --name mynodered nodered/node-red コンテナの /data(ボリューム) サーバーで動かす・環境をそろえる
Raspberry Pi など Debian 系 公式のインストールスクリプト(下) ~/.node-red 機器の近くで常に動かす
snap sudo snap install node-red snap の領域 公式は「Generally not recommended」
# Raspberry Pi・Debian 系(公式ドキュメントのスクリプト)
bash <(curl -sL https://github.com/node-red/linux-installers/releases/latest/download/install-update-nodered-deb)
sudo systemctl enable nodered.service   # 起動時に自動で動かす
node-red-start   # 起動してログを表示
node-red-stop    # 止める
node-red-log     # ログを見る

Raspberry Pi の公式ページは、Node.js 24 には32ビット版が無いこと、armv6 の Pi は対象外になったことを書いています。以前の 32 ビットの OS で動かしている場合は、OS の入れ替えか 4.x で使い続けるかを先に決めます。snap は、gcc・git・GPIO・exec ノードの外部コマンドが使えないため、公式も勧めていません。

Docker でも、-v を付けずに起動すると、コンテナを消したときにフローも消えます。公式の例のとおり /data にボリュームをつなぎます。Node.js の版を切り替える道具(nvm・fnm など)の選び方は、関連記事「Node.js バージョン管理|nvm・fnm・mise・Volta比較と実測」、npm のコマンドと package.json の書き方は関連記事「npm コマンド 一覧|package.json 書き方と実行結果・npm 12対応」で扱っています。

画面にボタンやグラフを並べる「ダッシュボード」は、以前よく使われた node-red-dashboard が npm で「No longer maintained」(保守終了)と表示され、代わりに @flowfuse/node-red-dashboard(Dashboard 2.0)か node-red-contrib-uibuilder が案内されています。これから作るなら代わりのほうを選びます。

Node-REDの性能とメモリ:実測値

この節では、Node-RED がどれくらい軽いか、HTTP の受け口がどれくらいの速さで応えるかが、手元の数字で分かります。

112MBnode_modules の大きさ276パッケージ・25秒。npm キャッシュは別に 122MB
2.8秒起動から応答まで7回の中央値。0.9〜4.0秒
141MB待機中のメモリ(RSS)5タブ・31ノード。負荷の後は 265MB

同じ JSON を返す GET /hello を、Node-RED と、Node.js の http モジュールだけで書いたサーバーで比べました。同時に10本ずつ、3,000回呼んだ結果です。マシンはほかの作業と共用で、負荷の平均が6〜10ある状態だったため、数字は目安です。

サーバー 1秒あたり 中央値 95%
Node-RED(http in→function→http response) 375〜587回 10.8〜14.8ms 47〜84ms
Node-RED + httpNodeAuth(Basic 認証) 450〜459回 15.7〜16.5ms 54〜58ms
Node.js の http だけ 650〜806回 7.4〜10.5ms 41〜48ms

Node-RED は Express の上で動き、要求ごとにいくつものノードを順に通すため、素の Node.js より遅くなります。Basic 認証を足すと、パスワードの照合(bcrypt)の分だけさらに遅くなりました。それでも1秒に数百回は応えたので、社内の連携やモックには困らない速さです。毎秒数千回を受ける API の本体には、普通のアプリとして書くほうが向きます。エディターを開いたときは、97回の通信で合計12MB ほど(圧縮を戻した大きさ)を読み込み、ログインの画面が出るまで約2.6秒でした。

function の無限ループはランタイム全体を止める

function ノードの「タイムアウト」は既定で 0(制限なし)です。while (true) {} を書いた function を、タイムアウト 0 のまま別のユーザーディレクトリで動かすと、5秒待ってもエディターが応答しなくなり(curl は exit 28 のタイムアウト)、kill(SIGTERM)でも止まらず、kill -9 が要りました。Node.js は1本の流れで JavaScript を実行するため、1つのノードが止まると、ほかのフローもエディターも巻き込まれます。タイムアウトを1秒にした function では、Error: Script execution timed out after 1000ms になり、ほかは動き続けました。止まったあとは --safe を付けて起動すると、フローを動かさずにエディターだけを開いて直せます。

$ npx node-red -u ./data --safe
[info] Server now running at http://127.0.0.1:18191/
[info] Flows stopped in safe mode. Deploy to start.

Node-REDとn8nの違い・使い分け(Dify・Zapierも)

この節では、似た道具の n8n・Dify・Zapier と比べて、Node-RED をどんなときに選ぶかが分かります。

Node-RED は「機器・プロトコル・社内の小さな連携」に強く、n8n は「SaaS どうしの連携と、実行の記録」に強い道具です。どちらもノードをつなぐ見た目ですが、流れるデータの単位、保存と反映のしかた、ライセンスが違います。n8n は別の記事「n8nとは?使い方を実行ログで解説|Webhook・料金・Zapier比較」で同じように動かして測っており、下の表の n8n の数字はその記事の値です。

観点 Node-RED 5.0.9 n8n 2.45.6
得意なこと MQTT・TCP・シリアルなど機器との通信、小さな API SaaS の連携、AI エージェント、業務の自動化
流れるデータ msg 1件ずつ(payload が中心) items(アイテムの配列)をまとめて渡す
標準のノード パレットに43個。サービス用は追加で入れる 標準ノード 445個(AI 系は別に127個)
反映のしかた デプロイした瞬間に本番として動く テストで実行→Publish で本番 URL が有効
実行の記録 標準では残らない(debug とログで見る) 実行履歴が画面に残り、やり直せる
初期のログイン なし(adminAuth を自分で設定) 初回にオーナーのアカウントを作る
大きさ・起動・メモリ 112MB・2.8秒・141MB 3.1GB・7.0秒・710MB
ライセンス Apache License 2.0 Sustainable Use License(独自)

Dify は、LLM(大規模言語モデル)を使うアプリやワークフローを作ることに特化した道具で、ノードの多くが「プロンプト」「知識の検索」「LLM の呼び出し」です。Dify の画面とノードは関連記事「Difyの使い方|ワークフローの作り方とノード一覧」で扱っています。Zapier はクラウドだけで動く有料のサービスで、自分のサーバーに置くことはできません。

やりたいこと 向く道具 理由
工場・家のセンサーの値を集めて保存・通知 Node-RED MQTT・シリアル・TCP が標準。Raspberry Pi で動く軽さ
API のモックや中継を手早く立てる Node-RED http in と function で数分。起動も速い
Slack・Google スプレッドシート・CRM をつなぐ n8n か Zapier 認証済みのサービス用ノードがそろっている
失敗した実行をあとで調べてやり直したい n8n 実行履歴が標準で残る
LLM で文書を検索して答えるアプリ Dify RAG・プロンプト管理が中心の作り
サーバーを持たずに少しだけ自動化 Zapier クラウドだけで完結する
大量のアクセスを受ける本番 API 普通のアプリとして書く Node-RED は素の Node.js より遅い(前の節)

Node-REDのよくあるエラー/つまずき

この節では、Node-RED で出やすいエラーの原文と、原因・直し方が分かります。すべて手元で起こしたものです(Node.js の版のエラーだけは起動処理のコードに書かれた文言)。

エラー原文 原因 直し方
[error] Unable to listen on http://127.0.0.1:18191/ と Error: port in use 同じポートで別の Node-RED(や他のアプリ)が動いている 動いているほうを PID を確かめて止めるか、-p で別のポートにする
Error loading settings file と SyntaxError: Unexpected identifier 'flowFile' settings.js の前の行のカンマ抜け 表示された行の1つ上を見る。node -e "require('./settings.js')" で事前に確かめる
Unsupported version of Node.js と Node-RED requires Node.js v22.9 or later 5.x に対して Node.js の版が足りない Node.js 22.9 以上(推奨 24)にするか、Node-RED 4.x を使う
Waiting for missing types to be registered: - ui_button 入っていないノードを含むフローを読み込んだ そのノードを入れるか、フローから消す。この間は全フローが止まり、/hello も 404 になった
TypeError: Cannot read properties of undefined (reading 'address') msg.payload.user が無いのに、その先を読んだ msg.payload.user?.address のように書くか、先に有無を確かめる
Error: Script execution timed out after 1000ms function の処理がタイムアウトを超えた ループを見直す。タイムアウト 0 のままだと全体が固まる
RequestError: connect ECONNREFUSED 127.0.0.1:18999 http request の宛先が動いていない・ポート違い 宛先を curl で確かめる。msg.statusCode に ECONNREFUSED が入るので switch で分けられる
Cannot GET /hello(404) メソッド違い・未デプロイ・safe モード・missing types http in のメソッドと URL、ログの Started flows を確かめる。POST 用の URL に GET しても 404 だった
401 Unauthorized と WWW-Authenticate: Bearer realm="Users" adminAuth があるのに、トークン無しで Admin API を呼んだ /auth/token でトークンを取り、Authorization: Bearer を付ける
{"error":"invalid_grant","error_description":"Invalid resource owner credentials"} ユーザー名かパスワードが違う(403) hash-pw で作り直したハッシュを settings.js に入れ、再起動する
Your flow credentials file is encrypted using a system-generated key. credentialSecret を決めていない settings.js で credentialSecret を決める。次のデプロイで暗号化し直される
Disconnected from broker: nodered-t191@mqtt://127.0.0.1:18831 MQTT ブローカーが止まった・ネットワークが切れた ブローカーを起こすと15秒間隔の再接続でつながる。切断中のデータは落ちうる

エラーが出たときは、次の順に見ると原因の場所が早く絞れます。

  1. 1起動ログの最後が Started flows かport in use・settings の構文・missing types はここで分かる
  2. 2ノードの下の状態表示とデバッグメッセージ赤い三角は設定の不足、切断の表示は接続先の問題
  3. 3debug ノードを途中に挟む「msg オブジェクト全体」を表示にして、どこで中身が変わるかを見る
  4. 4ログの [error] [ノード種類:名前]ノードに名前を付けておくと、どれが失敗したかすぐ分かる
  5. 5固まったら --safe で起動フローを動かさずにエディターを開き、原因のノードを直してデプロイ

よくある質問

この節では、Node-RED について検索でよく聞かれることに短く答えます。

Q. Node-RED の読み方は?
「ノードレッド」です。日本には Node-RED 日本ユーザ会があり、公式ドキュメントの日本語訳も公開されています。

Q. Node-RED は無料ですか?商用で使えますか?
無料です。Apache License 2.0 なので、商用の仕組みにも使えます。追加ノードはそれぞれのライセンスを確かめます。

Q. プログラミングを知らなくても使えますか?
inject・change・switch・debug だけでも簡単な流れは作れます。ただ、データの加工は function ノードに JavaScript を書く場面が多く、msg とオブジェクトの読み方が分かると、できることが大きく広がります。

Q. 画面を日本語にできますか?
できます。ブラウザの言語が日本語なら、メニューや「デプロイ」などの表示が日本語になりました。メニューの「ユーザ設定」→「表示」の「表示言語」でも切り替えられます。

Q. Windows で使えますか?
使えます。Node.js を入れ、npm install -g node-red を sudo を付けずに実行し、node-red で起動します(公式ドキュメントの手順)。

Q. フローはどこに保存されますか?
ユーザーディレクトリ(既定は ~/.node-red、Docker は /data)の flows.json です。デプロイするたびに、1つ前の版が .flows.json.backup に残ります。

Q. Node-RED を止めるには?
起動したターミナルで Ctrl+C です。サービスとして動かしているなら node-red-stop か systemctl で止めます。function の無限ループで固まったときは SIGTERM で止まらないことがあり、手元では kill -9 が要りました。

Q. 外部のサービス(Slack・Google など)にもつなげますか?
追加ノードを入れるか、http request ノードで各サービスの API を呼べばつなげます。ただ、認証の手間やノードのそろい方は n8n・Zapier のほうが上です。

Q. 自分で作った API にパスワードを付けるには?
settings.js の httpNodeAuth で Basic 認証を付けます。adminAuth はエディターと Admin API だけを守るため、http in の URL は守られません。

Q. Node-RED 4.x から 5.x に上げるときの注意は?
まず Node.js を 22.9 以上にします。ユーザーディレクトリを丸ごと控えてから上げ、ダッシュボードなどの追加ノードが 5.x に対応しているかを確かめます。

まとめ

  • Node-RED はノードを線でつないでフローを作るローコードツールで、MQTT・HTTP・機器との通信が得意。Apache License 2.0 で無料。
  • Node.js 22.9 以上で npm install node-red→npx node-red。手元では112MB・起動2.8秒・待機中141MB と軽かった。
  • 基本は inject→function→debug。function は msg を受けて msg を返し、配列で返すと出口を選べる。既定のコンテキストは再起動で消える。
  • 初期状態はエディターも Admin API もパスワード無し。uiHost・adminAuth・httpNodeAuth・credentialSecret を最初に決める。
  • 機器や小さな API なら Node-RED、SaaS の連携と実行履歴なら n8n。function の無限ループは全体を止めるので、タイムアウトと --safe を覚えておく。

参考・出典

確認日はいずれも 2026年10月29日です。

  • Node-RED「About」:https://nodered.org/about/
  • Node-RED Docs「Running Node-RED locally」:https://nodered.org/docs/getting-started/local
  • Node-RED Docs「Supported Node versions」:https://nodered.org/docs/faq/node-versions
  • Node-RED Docs「Securing Node-RED」:https://nodered.org/docs/user-guide/runtime/securing-node-red
  • Node-RED Docs「Running under Docker」:https://nodered.org/docs/getting-started/docker
  • Node-RED Docs「Running on Raspberry Pi」:https://nodered.org/docs/getting-started/raspberrypi
  • Node-RED Docs「Admin API:POST /flows」:https://nodered.org/docs/api/admin/methods/post/flows/
  • Node-RED「CHANGELOG」:https://github.com/node-red/node-red/blob/master/CHANGELOG.md
  • npm「node-red」:https://www.npmjs.com/package/node-red
  • Node-RED 日本ユーザ会:https://nodered.jp/

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「Node-REDとは?使い方を実行ログで解説|HTTP・MQTT・n8n比較」

株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。

WE ARE HIRING

RJCで一緒に開発しながら、
成長を楽しみませんか?

RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!

  • 127日年間休日
  • 12時間平均残業時間
  • 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!

ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ
参加受付中

AI駆動開発、 無料セミナー