【问题标题】:Cannot find module error from docker-composer (only on windows)无法从 docker-composer 中找到模块错误(仅在 Windows 上)
【发布时间】:2019-05-22 11:28:19
【问题描述】:

我们正在尝试使用 docker(docker-compose,因为我们打算在之后添加 mongodb)创建一个运行 node.js 的容器。

我们正在复制 Dockerfile 中的 package.json,然后在 docker-compose.yml 中挂载一个卷,其中包含要执行的源代码。

我们的项目结构如下。

我们希望将源文件夹挂载为卷。

我们的 package.json 文件

{
  "name": "node_package",
  "version": "1.0.0",
  "description": "node_package inside node_dir for node_service running on node_container",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "node source/index.js"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.17.0"
  }
}

我们的 Dockerfile

FROM node:10-alpine
WORKDIR /node_dir
COPY package*.json ./
RUN npm install

我们的 docker-compose.yml

version: "3"
services:

  node_service:

     build: .

     container_name: node_container

     user: node

     working_dir: "/node_dir"

     ports:
     - "8080:3000"

     volumes:
     - ./source:/node_dir/source

     command: npm start

现在,当我们在 macOS 上运行它时,它可以工作了。它将源文件夹挂载为卷,然后执行 command npm start。但是当我们在 windows 上尝试同样的操作时,我们会得到以下错误

找不到模块“node_dir/source/index.js”

为什么它可以在 mac 上运行,但不能在 windows 上运行?

这是我们的 index.js 文件

const express = require('express')
const app = express()
const port = 3000

app.get('/', (req, res) => res.send('Hello World!'))

app.listen(port, () => {console.log(`Example app listening on port ${port}!`)})

当我们在 Dockerfile 中复制源文件夹时,它可以在 Windows 上运行。但是,如果我们不复制 Dockerfile 中的源文件夹并将其作为卷挂载到 docker-compose.yml 中,那么 command npm start 将不起作用。

【问题讨论】:

  • 您是否尝试过删除 node_modules 文件夹并在 windows 机器上再次运行“npm install”?
  • 你的意思是我应该在 Windows 主机或容器镜像上运行“npm install”?
  • 好吧,你说'我们在 Windows 上尝试同样的方法' - 所以我假设你有一个在 Windows 上运行的 bash shell(或类似的东西),并且你正在使用一些 svn(git 等)来获取 repo,所以默认情况下你必须运行 npm install ,对吗?我只是建议删除 node_modules 文件夹并再次运行它。
  • 不,我们没有使用任何 repo。它只是一个简单的设置项目。我们只是手动复制文件。我们正在复制 package.json 并直接在 docker 镜像上运行 npm install。
  • 我们还尝试删除模块文件夹并再次运行它。它没有改变任何东西,因为它在作为卷安装在 docker 上的 index.js 文件上抛出错误(在 Windows 上运行)

标签: javascript node.js docker docker-compose dockerfile


【解决方案1】:

因为某些节点模块需要编译,所以在运行npm i npm 时获取与OS 兼容的模块,即Windows 中的node_module 文件夹与Mac 不同。

最佳解决方案:将 node_module 与 docker-compose 中的绑定挂载隔离。 所以编辑docker-compose.yml 来自:

volumes:
   - ./source:/node_dir/source

到:

volumes:
   - /node_dir/node_modules # isolate node_modules for compatible os
   - ./source:/node_dir/source

【讨论】:

  • 在我们当前的场景中,node_modules 不是已经被隔离了吗?因为 docker-compose.yml 正在将源文件夹从主机安装到 node_dir 目录中的容器。但是 node_modules 在 node_dir 目录中(由 npm install 使用 Dockerfile 在容器上生成,比挂载的源文件夹高一级)。我不明白如何在卷中声明“/node_dir/node_modules”将其隔离为兼容的操作系统?
  • 不,当您将 node_dir 目录绑定到 docker 容器时,文件系统是相同的主机操作系统而不是 linux 文件系统。当通过上述技术隔离node_modules时,node_modules移动到文件系统基于linux文件系统并且完全兼容的临时卷。
  • 它仍然无法正常工作。即使在隔离 /node_dir/node_modules 之后,错误也是一样的。
  • 哦,现在专注于代码知道 index.js 不是在容器中挂载(或复制),因此您必须将 index.js 复制到容器 /node_dir 才能解决问题。
  • 我可以在电报消息中帮助你。 my username: masihjahangiri
猜你喜欢
  • 2013-11-22
  • 1970-01-01
  • 1970-01-01
  • 2013-12-20
  • 2019-03-06
  • 2017-01-12
  • 1970-01-01
  • 1970-01-01
  • 2020-10-14
相关资源
最近更新 更多