本指南假设您对Docker和Docker命令行有一定基础了解。文中介绍了多种在Docker环境下运行Node-RED的方式,并支持多种架构(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获取详细的镜像、标签和清单信息。
例如:假设您正在运行树莓派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 run命令和docker compose文件在不同系统间更具灵活性和可互换性。
注意: 目前Docker的架构检测存在一个bug,无法正确识别arm32v6
架构(例如树莓派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版本起,我们还为那些在Alpine系统上运行不佳的含原生组件的节点提供了基于Debian的镜像。
当您使用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
来强制执行此设置。
查看维基获取权限的详细信息。
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 stack
或docker-compose
运行的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-RED的项目功能可以通过环境参数(NODE_OPTIONS)将Node.js运行时参数传递给容器。例如,要固定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 - 重大变更:已取消对树莓派原生GPIO的支持 | | — | 原生GPIO的替代方案是 node-red-node-pi-gpiod。
原生GPIO支持的缺点包括:
/dev/mem
访问权限docker stack
命令node-red-node-pi-gpiod
解决了所有这些缺点。使用 node-red-node-pi-gpiod
可以从单个 Node-RED 容器与多个树莓派的 GPIO 进行交互,并允许多个容器访问同一树莓派上的不同 GPIO。
node-red-node-pi-gpiod
的步骤node-red-node-pi-gpiod
。PiGPIOd守护进程
。详细安装说明请参阅node-red-node-pi-gpiod
的README。pi gpiod
节点。pi gpiod
节点以连接到PiGPIOd守护进程
。通常主机的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
以下是用户报告的常见问题及可能的解决方案列表。
查看维基获取权限的详细信息。
如果您在打开文件或访问主机设备时遇到权限被拒绝的错误,请尝试以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
Node-RED: 面向事件驱动应用的低代码编程平台。
版权所有 OpenJS基金会 及 Node-RED 贡献者。保留所有权利。OpenJS基金会 拥有注册商标并使用商标。有关 OpenJS基金会 的商标列表,请参阅我们的 商标政策 和 商标列表。未在 OpenJS基金会商标列表 中标注的商标™或注册®商标归其各自持有人所有。使用这些商标并不意味着与它们有任何关联或获得其认可。
The OpenJS Foundation | 使用条款 | 隐私政策 | OpenJS基金会章程 | 商标政策 | 商标列表 | Cookie政策