本指南假设您对 Docker 和 Docker 命令行有基本的了解。它描述了 Node-RED 在 Docker 下运行的多种方式,并支持多种架构(amd64、arm32v6、arm32v7、arm64v8 和 s390x)。
自 Node-RED 1.0 版本起,Docker Hub 上的存储库已重命名为 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 a docker named volume called `node_red_data` 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),我们可以更轻松地操作它,并且通过固定主机端口,我们知道我们处于熟悉的环境中。当然,这意味着我们一次只能运行一个实例……但我们一步一个脚印地来。
如果我们对所看到的一切感到满意,我们可以使用 Ctrl-p
Ctrl-q
分离终端 - 容器将继续在后台运行。
要重新附加到终端(以查看日志),请运行
docker attach mynodered
如果需要重新启动容器(例如在重启或 Docker 守护进程重启后)
docker start mynodered
并在需要时再次停止它
docker stop mynodered
Node-RED 镜像基于 官方 Node JS Alpine Linux 镜像,以使其尽可能小。使用 Alpine Linux 减少了构建镜像的大小,但删除了原生模块编译所需的标准依赖项。如果您想添加具有原生依赖项的依赖项,请在运行容器时使用缺失的包扩展 Node-RED 镜像,或构建新镜像,请参阅 docker-custom,其中扩展了 Node-RED Docker 项目中的 README.md。
有关详细的镜像、标签和清单信息,请参阅 Github 项目 README。
例如:假设您正在 Raspberry PI 3B 上运行,其架构为 arm32v7
。那么只需运行以下命令即可拉取镜像(标签为 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 运行命令和 docker compose 文件在系统之间更灵活和可交换。
注意:目前 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
自 Node-RED v3.1.0 起,我们还提供了基于 Debian 的镜像,适用于那些在 Alpine 上无法很好地工作的原生组件节点。
一旦您使用 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
目录。
注意:从版本 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_data
$ docker volume ls
DRIVER VOLUME NAME
local node_red_data
$ docker run -it -p 1880:1880 -v node_red_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_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_data:/data --name mynodered nodered/node-red
下面是一个 Docker Compose 文件的示例,可以通过 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:
以上 compose 文件
/data
目录持久化到 Docker 中的 node-red-data
卷有时,使用本地目录中的文件填充 Node-RED Docker 镜像会很有用(例如,如果您希望整个项目都保留在 git 存储库中)。为此,您希望您的本地目录看起来像这样
Dockerfile
README.md
package.json # add any extra nodes your flow needs into your own package.json.
flows.json # the normal place Node-RED store your flows
flows_cred.json # credentials your flows may need
settings.js # your settings file
注意:如果您希望将 /data 卷挂载到外部,则此方法不适用。如果您需要使用外部卷进行持久化,请改为将您的设置和流文件复制到该卷。
以下 Dockerfile 基于基本的 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
WORKDIR /data
COPY package.json /data
RUN npm install --unsafe-perm --no-update-notifier --no-fund --only=production
WORKDIR /usr/src/node-red
# 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
注意:package.json
文件必须在脚本部分包含一个启动选项。例如,默认容器如下所示
"scripts": {
"start": "node $NODE_OPTIONS node_modules/node-red/red.js $FLOWS",
...
虽然不是必需的,但最好尽早执行 COPY package... npm install...
步骤,因为尽管您在 Node-RED 中工作时 flows.json
会频繁更改,但您的 package.json
只会在您更改项目中的模块时更改。而且,由于当 package.json
更改时需要执行的 npm install
步骤有时会很耗时,因此最好在 Dockerfile 中尽早执行耗时且通常不变的步骤,以便可以重用这些构建镜像,从而使后续的整体构建更快。
当然,您永远不想在任何地方硬编码凭据,因此如果您需要在 Node-RED 项目中使用凭据,上面的 Dockerfile 将允许您在 settings.js
中包含此内容…
module.exports = {
credentialSecret: process.env.NODE_RED_CREDENTIAL_SECRET // add exactly this
}
…然后当您在 Docker 中运行时,您会向 run
命令添加一个环境变量…
docker run -e "NODE_RED_CREDENTIAL_SECRET=your_secret_goes_here"
您通常构建此 Dockerfile
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) 设置,默认为“flows.json”。这可以在运行时使用以下命令行标志进行更改。
docker run -it -p 1880:1880 -v node_red_data:/data -e FLOWS=my_flows.json nodered/node-red
注意:如果设置 -e FLOWS=""
,则流文件可以通过 settings.js
文件中的 flowFile 属性设置。
其他有用的环境变量包括
-e NODE_RED_ENABLE_SAFE_MODE=false
# 设置为 true 会在安全(未运行)模式下启动 Node-RED-e NODE_RED_ENABLE_PROJECTS=false
# 设置为 true 会在启用项目功能的情况下启动 Node-REDNode.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 用户定义桥接在 Docker 运行时中“内部”链接容器。
在使用桥接之前,需要创建它。以下命令将创建一个名为 iot 的新桥接
docker network create iot
然后所有需要通信的容器都需要使用 –network 命令行选项添加到同一个桥接中
docker run -itd --network iot --name mybroker eclipse-mosquitto mosquitto -c /mosquitto-no-auth.conf
(除非您想将端口 1883 全局公开……因为我们下面会施展魔法)
然后运行 nodered docker,也添加到同一个桥接中
docker run -itd -p 1880:1880 --network iot --name mynodered nodered/node-red
在同一用户定义桥接上的容器可以利用桥接提供的内置名称解析,并使用容器名称(使用 –name 选项指定)作为目标主机名。
在上面的示例中,Node-RED 应用程序可以使用主机名mybroker访问代理。
然后像下面这样的简单流显示 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
等添加到代理运行命令中。
| v1.0 - 破坏性更改:已删除 Raspberry PI 的原生 GPIO 支持 | | — | 原生 GPIO 的替代是 node-red-node-pi-gpiod。
原生 GPIO 支持的缺点是
/dev/mem
node-red-node-pi-gpiod
修复了所有这些缺点。使用 node-red-node-pi-gpiod
,可以从单个 Node-RED 容器与多个 Raspberry Pi 的 gpio 交互,并且多个容器可以访问同一 Pi 上的不同 gpio。
node-red-node-pi-gpiod
的步骤node-red-node-pi-gpiod
。PiGPIOd daemon
。有关详细的安装说明,请参阅 node-red-node-pi-gpiod
README。pi gpiod
节点。pi gpiod
节点以连接到 PiGPIOd daemon
。通常,主机将具有 IP 172.17.0.1 端口 8888 - 但并非总是如此。您可以使用 docker exec -it mynodered ip route show default | awk '/default/ {print $3}'
进行检查。注意:有一个贡献的 gpiod 项目,如果需要,它可以在自己的容器中运行 gpiod 而不是在主机上。
要访问主机串口,您可能需要将容器添加到 dialout
组。这可以通过在启动命令中添加 --group-add dialout
来启用。例如
docker run -it -p 1880:1880 -v node_red_data:/data --group-add dialout --name mynodered nodered/node-red
以下是用户报告的常见问题列表及其可能的解决方案。
有关权限的详细信息,请参阅wiki。
如果您看到打开文件或访问主机设备时出现权限被拒绝错误,请尝试以 root 用户身份运行容器。
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
或在 docker-compose 文件中
node-red:
environment:
- TZ=America/New_York
参考:https://groups.google.com/forum/#!topic/node-red/ieo5IVFAo2o
版权所有 OpenJS Foundation 和 Node-RED 贡献者。保留所有权利。OpenJS Foundation 已注册商标并使用商标。有关 OpenJS Foundation 商标列表,请参阅我们的商标政策和商标列表。未在OpenJS Foundation 商标列表中指明的商标和徽标是其各自持有人的商标™ 或注册® 商标。使用它们不表示与它们的任何关联或认可。
OpenJS Foundation | 使用条款 | 隐私政策 | OpenJS Foundation 章程 | 商标政策 | 商标列表 | Cookie 政策