当将主机目录挂载为网络共享时,babel-watch 在 windows 主机上的 docker 容器中不起作用

babel-watch doesn't work from docker container on windows host when mounting a host directory as a network share

我在 Windows 上使用 docker,我的 src 目录是 mounted as a network share inside the docker container(而不是 COPY)。所以 docker 里面的 /var/app/server 实际上是一个网络共享,它在我的主机上的实际位置是 C:\...project\server。 [旁注,我不熟悉 docker 如何在 linux 上工作,就像它是否仍然使用网络共享在 linux 上挂载一样?因为如果不是,那么这可能只是 windows 问题]

我正在使用使用 mkfifo 的 babel-watch,因为它在 docker 容器 (VM) 内 运行 mkfifo 无法在其中创建文件管道网络共享目录。 [旁注:babel-watch 实际上确实可以在 windows 外部 docker 上使用具有 mkfifo.exe 实用程序的 cygwin 工作]

server_1  | mkfifo: cannot create fifo `/var/app/server/116521-16-pz2v9g.ma216skyb9': Operation not permitted
server_1  | Unable to create named pipe with mkfifo. Are you on linux/OSX?

有什么解决方法吗?

我尝试 editing babel-watch source 让 mkfifo 在 /var/app/var 中创建一个文件(它仍然在 docker 容器的范围内)并且虽然这种方式 mkfifo 实际上有效,但 babel-watch 看不到文件更改。我想从根本上说,文件更改信息无法通过网络共享屏障传播 - /var/app/server(挂载点)到 /var/app(docker 内的真实目录)。

mkfifo 需要 Linux/OSX 环境,而 /var/app/server 是从 Windows 安装的。所以它不起作用。所以你应该 ADDCOPY 而不是 mount volume

我最近 运行 研究了这个问题并做了一些挖掘。

如果您查看 babel-watch source(在撰写本文时),您会发现它试图在 OS 的临时目录中创建命名管道。

function generateTempFilename() {
  const now = new Date();
  return path.join(os.tmpdir(), [
    now.getYear(), now.getMonth(), now.getDate(),
    '-',
    process.pid,
    '-',
    (Math.random() * 0x100000000 + 1).toString(36),
  ].join(''));
}

在我们的 docker 容器中 $TMPDIR 未设置,这导致在当前工作目录中创建命名管道。设置它会改变这个:

TEMP_DIR=/tmp babel-watch index.js

这意味着 mkfifo 调用未针对 windows 文件系统。然而,这并没有解决未在 Windows 文件系统上选取更改的问题。要检测更改,您可以使用轮询标志 --use-polling。这使得命令:

TEMP_DIR=/tmp babel-watch --use-polling index.js

将这两个一起使用允许我们使用 Docker 中 docker 容器中的 babel-watch for Windows.