- 技術 💻
Node-REDとは?使い方を実行ログで解説|HTTP・MQTT・n8n比較
結論
Node-RED(ノードレッド)は、四角い「ノード」を線でつないで処理の流れ(フロー)を作る、Node.js 製のローコード開発ツールです。センサーや MQTT のデータを集める、Web API を受けて返す、決まった時刻に処理を動かす、といった「つなぐ仕事」を少ないコードで作れます。
この記事でわかること
- npm で入れて5分で最初の出力を出す手順と、その起動ログ
- inject→function→debug、HTTP の受け口、MQTT を動かした実物
- 認証が無い初期状態の危うさ、エラー原文12件、n8n との使い分け
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(グローバル)を案内していますが、試すだけなら作業フォルダに入れるほうが、消すときにフォルダごと消せて後始末が楽です。
Node.js の版を確かめる
node -v が v22.9 以上か見る。5.x は Node.js 22.9 以上が要り、公式は 24 を推奨している。足りなければ先に Node.js を更新する。
作業フォルダに入れる
npm init -y のあと npm install node-red。手元では276個のパッケージが入り、25秒、node_modules は112MB だった。
127.0.0.1 だけで起動する
npx node-red -u ./data -D uiHost=127.0.0.1。-u で設定とフローの置き場所を決め、-D で待ち受けアドレスを自分の PC だけに絞る。
ブラウザで開く
ログに出た Server now running at http://127.0.0.1:1880/ を開く。初回は Node-RED 5.0 の新機能を紹介するツアーが出るので、右上の × で閉じる。
inject と debug をつないでデプロイ
左のパレットから inject と debug を置いて線でつなぎ、右上の「デプロイ」。inject の左の四角を押すと、右の「デバッグメッセージ」に時刻の数字が出る。
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 を置くのが決まりです。
catch ノード
指定したノード(または同じタブの全ノード)のエラーを受け取る。msg.error に文言と発生元が入る。
400・500 を返す道を作る
node.error(文, msg)
function の中で、自分でエラーにする。msg を一緒に渡すと catch に届く。
入力の検査に使う
status ノード
ノードの状態表示(接続・切断など)が変わったときに msg を出す。
MQTT の切断を通知する
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 から送信と受信の両方を行いました。
- mqtt-broker の設定ノード:サーバー
127.0.0.1、ポート18831、クライアント IDnodered-t191、MQTT 3.1.1。 - 送る側:前の節の switch の「30度以上」の出口に mqtt out をつなぎ、トピック
factory/line1/alert、QoS 1 で送る。 - 受ける側:別のタブに 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 の版やメモリの量を返していました。
公開の前にやってはいけないこと
見分ける問い:「同じネットワークの他人がエディターを開けるか」
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 の受け口がどれくらいの速さで応えるかが、手元の数字で分かります。
同じ 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起動ログの最後が Started flows かport in use・settings の構文・missing types はここで分かる
- 2ノードの下の状態表示とデバッグメッセージ赤い三角は設定の不足、切断の表示は接続先の問題
- 3debug ノードを途中に挟む「msg オブジェクト全体」を表示にして、どこで中身が変わるかを見る
- 4ログの [error] [ノード種類:名前]ノードに名前を付けておくと、どれが失敗したかすぐ分かる
- 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期連続の黒字決算。