使用 resin.io 部署时,如何更新 node-red/node-red-docker 映像中的 settings.js?

How to update the settings.js in node-red/node-red-docker image when deployed with resin.io?

我正在使用包含以下内容的 Docker 文件,我在 raspberry pi.

上使用 resin.io 进行部署
FROM nodered/node-red-docker:rpi-v8
USER root
RUN sudo setcap 'cap_net_bind_service=+ep'  $(eval readlink -f `which node`)
USER node-red

我也想更新 Node-RED 使用的 settings.js,但我不知道该怎么做。

我创建了一个文件 settings.js 并在 运行 命令之后将以下行添加到我的 Docker 文件中...它确实由 [=26 构建并部署了=] 没有任何错误。

COPY settings.js /data/

...但是在检查 /data/ 文件夹时我发现 settings.js 没有更新。我仍然可以看到旧的 settings.js,它是由先前的部署和容器启动自动创建的。

仅供参考,我容器的 /data 文件夹的内容:

node-red@997563c:~$ ls -l /data
total 24
-rw-r--r-- 1 node-red node-red  283 Oct 28 08:57 flows.json
drwxr-xr-x 3 node-red node-red 4096 Oct 27 10:44 lib
drwxr-xr-x 3 root     root     4096 Oct 26 22:27 node-red
-rw-r--r-- 1 node-red node-red  120 Oct 27 16:44 package.json
-rw-r--r-- 1 node-red node-red 8091 Oct 27 10:44 settings.js
node-red@997563c:~$

仅供参考,下面是涵盖 Node-RED 应用程序启动的容器日志文件:

28.10.18 11:18:03 (+0100) Starting service 'main sha256:472f9797c9288bc3d5a9147597fd33fb982ab34f4eb0e467f70842f05a421f3b'
28.10.18 11:18:04 (+0100)  main  mount: only root can use "--types" option
28.10.18 11:18:04 (+0100)  main  mount: only root can use "--move" option
28.10.18 11:18:04 (+0100)  main  mount: only root can use "--move" option
28.10.18 11:18:04 (+0100)  main  mount: only root can use "--move" option
28.10.18 11:18:04 (+0100)  main  mount: only root can use "--move" option
28.10.18 11:18:04 (+0100)  main  umount: /dev: umount failed: Operation not permitted
28.10.18 11:18:04 (+0100)  main  mount: only root can use "--move" option
28.10.18 11:18:04 (+0100)  main  ln: cannot remove ‘/dev/ptmx’: Permission denied
28.10.18 11:18:04 (+0100)  main  mount: only root can use "--types" option
28.10.18 11:18:04 (+0100)  main  /sbin/udevd
28.10.18 11:18:04 (+0100) Started service 'main sha256:472f9797c9288bc3d5a9147597fd33fb982ab34f4eb0e467f70842f05a421f3b'
28.10.18 11:18:05 (+0100)  main  npm info it worked if it ends with ok
28.10.18 11:18:05 (+0100)  main  npm info using npm@5.0.3
28.10.18 11:18:05 (+0100)  main  npm info using node@v8.1.3
npm info lifecycle node-red-docker@1.0.0~prestart: node-red-docker@1.0.0
npm info lifecycle node-red-docker@1.0.0~start: node-red-docker@1.0.0
28.10.18 11:18:05 (+0100)  main
28.10.18 11:18:05 (+0100)  main  > node-red-docker@1.0.0 start /usr/src/node-red
28.10.18 11:18:05 (+0100)  main  > node $NODE_OPTIONS node_modules/node-red/red.js -v $FLOWS "--userDir" "/data"
28.10.18 11:18:05 (+0100)  main
28.10.18 11:18:08 (+0100)  main  28 Oct 10:18:08 - [info]
28.10.18 11:18:08 (+0100)  main
28.10.18 11:18:08 (+0100)  main  Welcome to Node-RED
28.10.18 11:18:08 (+0100)  main  ===================
28.10.18 11:18:08 (+0100)  main
28.10.18 11:18:08 (+0100)  main  28 Oct 10:18:08 - [info] Node-RED version: v0.19.4
28.10.18 11:18:08 (+0100)  main  28 Oct 10:18:08 - [info] Node.js  version: v8.1.3
28.10.18 11:18:08 (+0100)  main  28 Oct 10:18:08 - [info] Linux 4.14.39 arm LE
28.10.18 11:18:09 (+0100)  main  28 Oct 10:18:09 - [info] Loading palette nodes
28.10.18 11:18:12 (+0100)  main  28 Oct 10:18:12 - [info] Settings file  : /data/settings.js
28.10.18 11:18:12 (+0100)  main  28 Oct 10:18:12 - [info] Context store  : 'default' [module=memory]
28.10.18 11:18:12 (+0100)  main  28 Oct 10:18:12 - [info] User directory : /data
28.10.18 11:18:12 (+0100)  main  28 Oct 10:18:12 - [warn] Projects disabled : editorTheme.projects.enabled=false
28.10.18 11:18:12 (+0100)  main  28 Oct 10:18:12 - [info] Flows file     : /data/flows.json
28.10.18 11:18:12 (+0100)  main  28 Oct 10:18:12 - [info] Server now running at http://127.0.0.1:80/
28.10.18 11:18:12 (+0100)  main  28 Oct 10:18:12 - [warn]
28.10.18 11:18:12 (+0100)  main
28.10.18 11:18:12 (+0100)  main  ---------------------------------------------------------------------
28.10.18 11:18:12 (+0100)  main  Your flow credentials file is encrypted using a system-generated key.
28.10.18 11:18:12 (+0100)  main
28.10.18 11:18:12 (+0100)  main  If the system-generated key is lost for any reason, your credentials
28.10.18 11:18:12 (+0100)  main  file will not be recoverable, you will have to delete it and re-enter
28.10.18 11:18:12 (+0100)  main  your credentials.
28.10.18 11:18:12 (+0100)  main
28.10.18 11:18:12 (+0100)  main  You should set your own key using the 'credentialSecret' option in
28.10.18 11:18:12 (+0100)  main  your settings file. Node-RED will then re-encrypt your credentials
28.10.18 11:18:12 (+0100)  main  file using your chosen key the next time you deploy a change.
28.10.18 11:18:12 (+0100)  main  ---------------------------------------------------------------------
28.10.18 11:18:12 (+0100)  main
28.10.18 11:18:12 (+0100)  main  28 Oct 10:18:12 - [info] Starting flows
28.10.18 11:18:12 (+0100)  main  28 Oct 10:18:12 - [info] Started flows

仅供参考,我的 docker 容器的 df 输出:

node-red@997563c:~$ df
Filesystem     1K-blocks   Used Available Use% Mounted on
none             6794760 748316   5677608  12% /
tmpfs              65536      0     65536   0% /dev
/dev/mmcblk0p6   6794760 748316   5677608  12% /data
none              306201 245637     40494  86% /lib/modules
tmpfs             499556      0    499556   0% /tmp/resin
shm                65536      0     65536   0% /dev/shm
tmpfs             499556  10024    489532   3% /host/run/dbus
node-red@997563c:~$

第一次更新(2018-10-28):

以下 2 个链接描述了 settings.js 如何作为 node-RED 的 Docker 构建脚本的一部分提供。所以这在技术上是可行的,但目前我不知道如何使用官方 nodered/node-red-docker 存储库

  1. https://github.com/resin-io-projects/balena-node-red
  2. https://medium.com/@knolleary/deploying-node-red-applications-to-devices-using-resin-io-58d2042cdb0c

好的,所以问题是 `/data' 被挂载在 docker 图像中的所有内容之上。

/data 的内容将由您推送到 resin.io 设备的 docker 图片的先前版本确定。

我可以看到 2 个选项:

  1. 擦除整个图像并重新开始。这只有效,因为你还 "playing"。这在生产环境中是不可能的。
  2. 登录容器并edit/replacesettings.js并重启

根本原因:

这个问题实际上是由于 resin.io 正在使用 /data 文件夹进行永久存储,并且文件只能在第一次为该设备创建容器时复制到该文件夹.因此容器的后续部署不会更改 /data 文件夹的内容。

这在https://docs.resin.io/learn/develop/runtime/#persistent-storage中也有描述。相关部分复制粘贴如下:

Persistent Storage

If you have data or configurations that you would like to persist through application and host OS updates, you have the option to keep them in persistent storage. Persistent storage is a good place to write system logs and other application data that should remain untouched even as your code changes

...

resinOS v2.12.0 and above

Beginning with resinOS v2.12.0, persistent storage is handled through named volumes. The behavior is much the same as persistent storage on older host OS versions. In fact, for single-container applications, the default docker-compose.yml sets up a resin-data named volume that links to a /data directory in the container. The only difference between this and earlier versions is that accessing this data via the host OS is done at /var/lib/docker/volumes/_resin-data/_data, rather than the /mnt/data/resin-data/ location used with earlier host OS versions.

Named volumes can be given arbitrary names and can be linked to a directory in one or more containers. As long as every release of the application includes a docker-compose.yml and the volume name does not change, the data in the volume will persist across updates.

When using named volumes, note that:

If a device is moved to a new application, the old /data folder will be automatically purged. During the build process, data added to a container directory that is configured to link to a named volume will be copied to the volume the first time it's created on the device.

解决方案:

为了保证Dockerfile中的如下指令被有效执行:

COPY settings.js /data/

您必须在 resin.io 控制面板中执行以下步骤。

  1. 创建一个虚拟应用程序
  2. 将设备移动到虚拟应用程序
  3. 将设备移回原来的应用程序

第 2 步将确保 /data 文件夹被完全擦除。

步骤 3 将确保 settings.js 有效地复制到 /data 文件夹,因为这是映像第一次部署到该设备上。

仅供参考:URL https://docs.resin.io/learn/manage/actions/#move-to-another-application 描述了操作 移动到另一个应用程序

在该页面上您还可以找到以下声明:

Warning: For devices running resinOS version 2.12.0 and above, data in persistent storage (named volumes) is automatically purged when a device is moved to a new application.