Docker-compose:npm 安装成功后卷中不存在 node_modules [英] Docker-compose: node_modules not present in a volume after npm install succeeds

查看:84
本文介绍了Docker-compose:npm 安装成功后卷中不存在 node_modules的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个提供以下服务的应用:

I have an app with the following services:

  • web/ - 在端口 5000 上保存并运行 Python 3 Flask Web 服务器.使用 sqlite3.
  • worker/ - 有一个 index.js 文件,它是一个队列的 worker.Web 服务器使用 json API 通过端口 9730 与此队列交互.worker 使用 redis 进行存储.worker 还在本地将数据存储在文件夹 worker/images/
  • web/ - holds and runs a python 3 flask web server on port 5000. Uses sqlite3.
  • worker/ - has an index.js file which is a worker for a queue. the web server interacts with this queue using a json API over port 9730. The worker uses redis for storage. The worker also stores data locally in the folder worker/images/

现在这个问题只涉及worker.

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 中,正如我所期望的那样.

When I run docker-compose build, everything works as expected and all npm modules are installed in /worker/node_modules as I'd expect.

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 时,我看到了这个错误:

But when I do docker-compose up, I see this error:

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 中没有任何模块(在主机或容器中).

Turns out none of the modules are present in /worker/node_modules (on host or in the container).

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

If on the host, I npm install, then everything works just fine. But I don't want to do that. I want the container to handle dependencies.

这里出了什么问题?

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

(Needless to say, all packages are in package.json.)

推荐答案

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

This happens because you have added your worker directory as a volume to your docker-compose.yml, as the volume is not mounted during the build.

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

When docker builds the image, the node_modules directory is created within the worker directory, and all the dependencies are installed there. Then on runtime the worker directory from outside docker is mounted into the docker instance (which does not have the installed node_modules), hiding the node_modules you just installed. You can verify this by removing the mounted volume from your docker-compose.yml.

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

A workaround is to use a data volume to store all the node_modules, as data volumes copy in the data from the built docker image before the worker directory is mounted. This can be done in the docker-compose.yml like this:

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

我不完全确定这是否会给图像的可移植性带来任何问题,但由于您似乎主要使用 docker 来提供运行时环境,因此这应该不是问题.

I'm not entirely certain whether this imposes any issues for the portability of the image, but as it seems you are primarily using docker to provide a runtime environment, this should not be an issue.

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

If you want to read more about volumes, there is a nice user guide available here: https://docs.docker.com/userguide/dockervolumes/

Docker 已经改变了它的语法,要求在相对于 docker-compose.yml 文件的文件中安装前导 ./.

Docker has since changed it's syntax to require a leading ./ for mounting in files relative to the docker-compose.yml file.

这篇关于Docker-compose:npm 安装成功后卷中不存在 node_modules的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆