docker 撰写卷上的节点监视不会注册删除事件



我有一个简单的 Node.js HTTP 服务器在 docker 容器内运行。其中一个基本结构文件夹使用docker-compose.yml中的volume来镜像主机和容器目录。

在 Node 服务器中,我设置了一个观察程序来跟踪卷目录中的更改,使用 NPM 包chokidar(尽管我已经尝试了多个其他观察程序,结果相同(。

const watcher = require("chokidar");
watcher
.watch("./app/experiments", { depth: 0, ignoreInitial: true })
.on("all", (event, path) => {
console.log(event);
// ... DO SOME EXPRESS AND WEBPACK STUFF 
});

当我在本地运行 Node 服务器时,观察程序会正确选取对监视目录的更改。在这种情况下,chokidar将这些报告为addDirunlinkDir,它们对应于我运行的脚手架脚本,用于在目录中添加或删除新文件夹(稍后通过express.static()提供(。

标准输出:

> addDir
> EXPERIMENT ADDED!
> ...
> unlinkDir
> EXPERIMENT DELETED!

但是,当我将应用程序移植到 docker 容器中时,行为以一种非常奇怪的方式发生了变化。当我在卷目录中创建新文件夹时,我继续收到addDir事件,但我不再收到unlinkDir(删除(事件!请注意,仅当我在主机上的卷目录中添加/删除文件时,才会发生这种情况。如果我在 docker 容器内的该目录中添加/删除文件,我的观察程序会正确报告所有这些事件。

无论哪种情况,卷目录都会正确镜像自身。 例如,文件实际上被删除或添加,我可以验证它们在主机上的存在,并通过炮击 docker 容器并运行ls.

任何码头工人天才都有圣人的智慧来解释为什么会发生这种情况?

关键内容:

OS X 10.13.6

码头工人工具箱:

  • 码头工人 18.03.0-ce
  • 码头工人加工 0.14.0
  • docker-compose 1.20.1
  • 虚拟盒子 5.2.18R124319

Dockerfile:

FROM node:8.12.0
WORKDIR /usr/dd-labs
COPY package*.json ./
RUN npm install
COPY app/ ./app
COPY server.js ./
COPY webpack/ ./webpack
EXPOSE 8080

Docker-compose.yml:

version: "2"
services:
app:
image: #someImageName
build: .
ports:
- "8080:8080"
labels:
io.rancher.container.pull_image: always
environment:
VIRTUAL_HOST: labs.docker
volumes:
- ./app:/usr/dd-labs/app
command: [sh, -c, "npm run start:dev"]

您可能正在使用 Docker for Windows,众所周知,它不支持从主机到容器的文件系统事件传播。

解决方法是在开发环境中使用轮询。有了chokidar,你会想要usePolling: true选择。