Docker voume 不会检测主机上 Node.js 脚本所做的文件更改

Docker voume does not detect file changes made by a Node.js script on host

提问人:botf 提问时间:11/13/2023 更新时间:11/13/2023 访问量:29

问:

我有两个 Node.js 脚本,一个名为将行附加到一个名为(每 500 毫秒)的文件,另一个名为监视对 .appender.jslogwatcher.jslog

// appender.js
const { createWriteStream } = require("fs")

const stream = createWriteStream("log")

setInterval(
    () => stream.write("Hello\n"), 
    500
)
// watcher.js
const fs = require('fs')

fs.watch("log", console.log)

当我在一个终端和另一个终端上使用在主机上运行这两个脚本时,可以检测到所做的更改。appender.jswatcher.jsnode appender.jsnode watcher.js

但是当我在主机和 docker 容器中运行时,情况就不同了。appender.jswatcher.js

在此设置中,我有一个 Dockerfile 来构建观察程序。 该映像是使用 构建的。docker build -t watcher:latest .

FROM node:18

WORKDIR /usr/watcher

COPY watcher.js watcher.js

CMD [ "node", "watcher.js" ]

构建 docker 映像后,我在一个终端和另一个终端中运行。 但在此设置中,仅当追加程序开始和结束时才会检测到更改,而每 500 毫秒追加行时不会检测到更改。node appender.jsdocker run --rm -it --name watcher -v $(pwd)/log:/usr/watcher/log watcher:latest

另一方面,当我在共享相同卷的单独 docker 容器中运行这两个脚本时,一切正常。

appender 的 dockerfile 为:

FROM node:18

WORKDIR /usr/appender

COPY appender.js appender.js

CMD [ "node", "appender.js" ]

我用 构建映像。 一旦构建,我运行 .docker build -t appender:latest -f Dockerfile.appender .docker run --rm -it -v $(pwd)/log:/usr/appender/log --name appender appender:latest

我还测试了 appender 在 docker 容器中运行,观察器在主机中运行的场景。

在此方案中,我为观察程序和 . 在此设置中,观察程序会正确检测更改。node watcher.jsdocker run --rm -it -v $(pwd)/log:/usr/appender/log --name appender appender:latest

因此,唯一未按预期工作的情况是当观察程序位于容器中,而追加程序位于主机中时。

为什么当观察程序位于 docker 容器中时,无法检测到主机上运行的 appender 所做的更改?

另外,我在macOS Ventura 13.3.1(M1)上。 我的 docker 版本是 .Docker version 20.10.17, build 100c701

节点.js docker

评论


答:

0赞 Hans Kilian 11/13/2023 #1

由于 Mac 在仿真下运行 amd64 容器,您可能会遇到问题。请参阅此处 https://docs.docker.com/desktop/troubleshoot/known-issues/“适用于 Apple 芯片的 Mac”选项卡:

但是,尝试在 Apple 芯片上运行基于 Intel 的容器 仿真下的机器可能会崩溃,因为 qemu 有时无法运行 容器。此外,文件系统更改通知 API (inotify) 不要在 QEMU 仿真下工作。即使容器确实在运行 在仿真下,它们会变慢并使用更多内存 比原生等价物。

inotify 是用于发送文件系统更新事件的机制。

解决此问题的一种方法可能是让观察程序使用轮询来检查更新。尝试将观察程序的环境变量设置为“,当它在容器中运行时。CHOKIDAR_USEPOLLING1

评论

0赞 botf 11/13/2023
谢谢你的回答。我尝试运行我的容器,但行为是相同的。另外,我已经检查了我的图像,它似乎是返回的手臂图像。此外,运行返回 .所以,我认为一切都在没有 qemu 的情况下运行。我错了吗?docker run --rm -it -e CHOKIDAR_USEPOLLING=1 -v $(pwd)/log:/usr/watcher/log --name watcher watcher:latestdocker image inspect cdae858c43d6 --format '{{ .Os }}/{{ .Architecture }}'linux/arm64docker run --rm -it --name watcher watcher:latest lscpuArchitecture: aarch64
0赞 Hans Kilian 11/13/2023
不,你是对的。这听起来像是它没有在模拟器中运行。那么它一定是别的东西。