Docker-compose:npm install 成功后,node_modules 不存在于卷中

新手上路,请多包涵

我有一个具有以下服务的应用程序:

  • web/ 在端口 5000 上保存并运行 python 3 flask web 服务器。使用 sqlite3。
  • worker/ - 有一个 index.js 文件,它是队列的工作人员。 Web 服务器使用 json API 通过端口 9730 与此队列交互。 worker 使用 redis 进行存储。工作人员还将数据本地存储在文件夹中 worker/images/

现在这个问题只涉及 worker

worker/Dockerfile

 FROM node:0.12

WORKDIR /worker

COPY package.json /worker/
RUN npm install

COPY . /worker/

docker-compose.yml

 redis:
    image: redis
worker:
    build: ./worker
    command: npm start
    ports:
        - "9730:9730"
    volumes:
        - worker/:/worker/
    links:
        - redis

当我运行 docker-compose build 时,一切都按预期工作,并且所有 npm 模块都安装在 /worker/node_modules 正如我所期望的那样。

 npm WARN package.json unfold@1.0.0 No README data

> phantomjs@1.9.2-6 install /worker/node_modules/pageres/node_modules/screenshot-stream/node_modules/phantom-bridge/node_modules/phantomjs
> node install.js

<snip>

但是当我做 docker-compose up 时,我看到了这个错误:

 worker_1 | Error: Cannot find module 'async'
worker_1 |     at Function.Module._resolveFilename (module.js:336:15)
worker_1 |     at Function.Module._load (module.js:278:25)
worker_1 |     at Module.require (module.js:365:17)
worker_1 |     at require (module.js:384:17)
worker_1 |     at Object.<anonymous> (/worker/index.js:1:75)
worker_1 |     at Module._compile (module.js:460:26)
worker_1 |     at Object.Module._extensions..js (module.js:478:10)
worker_1 |     at Module.load (module.js:355:32)
worker_1 |     at Function.Module._load (module.js:310:12)
worker_1 |     at Function.Module.runMain (module.js:501:10)

事实证明, /worker/node_modules (在主机或容器中)中不存在任何模块。

如果在主机上,我 npm install ,那么一切正常。但我不想那样做。我希望容器处理依赖项。

这里出了什么问题?

(不用说,所有的包都在 package.json 中。)

原文由 KGo 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 856
1 个回答

发生这种情况是因为您已将 worker 目录作为卷添加到 docker-compose.yml ,因为在构建期间未安装该卷。

当 docker 构建图像时, node_modules worker 中创建,所有依赖项都安装在那里。然后在运行时将 worker 目录从外部 docker 安装到 docker 实例中(没有安装 node_modules ),隐藏 node_modules 您可以通过从 docker-compose.yml 中删除已安装的卷来验证这一点。

解决方法是使用数据卷来存储所有 node_modules ,因为数据卷在挂载 worker 目录之前从构建的 docker 映像中复制数据。这可以在 docker-compose.yml 中完成,如下所示:

 redis:
    image: redis
worker:
    build: ./worker
    command: npm start
    ports:
        - "9730:9730"
    volumes:
        - ./worker/:/worker/
        - /worker/node_modules
    links:
        - redis

我不完全确定这是否会对图像的可移植性造成任何问题,但由于您似乎主要使用 docker 来提供运行时环境,所以这应该不是问题。

如果你想阅读更多关于卷的信息,这里有一个很好的用户指南: https ://docs.docker.com/userguide/dockervolumes/

编辑:从那以后,Docker 改变了它的语法,要求前导 ./ 用于安装在与 docker-compose.yml 文件相关的文件中。

原文由 FrederikNS 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题