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

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

问题描述

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




  • web / 在port 5000上保存并运行一个python 3烧瓶Web服务器。使用sqlite3。

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



这个问题只涉及 worker



worker / Dockerfile



  FROM node:0.12 

WORKDIR / worker

COPY包.json / worker /
运行npm安装

COPY。 / worker /



docker-compose.yml



  redis:
image:redis
worker:
build:./worker
命令: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没有README数据

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

< snip>

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

  worker_1 |错误:找不到模块'async'
worker_1 |在Function.Module._resolveFilename(module.js:336:15)
worker_1 |在Function.Module._load(module.js:278:25)
worker_1 |在Module.require(module.js:365:17)
worker_1 | at require(module.js:384:17)
worker_1 |在Object。< anonymous> (/worker/index.js:1:75)
worker_1 |在Module._compile(module.js:460:26)
worker_1 |在Object.Module._extensions..js(module.js:478:10)
worker_1 |在Module.load(module.js:355:32)
worker_1 |在Function.Module._load(module.js:310:12)
worker_1 |在Function.Module.runMain(module.js:501:10)

没有一个模块存在于 / worker / node_modules (在主机或容器中)。



如果在主机上,我 npm install ,那么一切都正常。但我不想这样做。我想要容器处理依赖关系。



这里有什么问题?



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

解决方案

这是因为你有在您的 docker-compose.yml 中将您的 worker 目录添加为一个卷,因为在构建期间未装载卷



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



解决方法是使用一个用于存储所有 node_modules 的数据卷,因为数据卷从位于 worker 之前的已建立的Docker映像的数据中复制目录已安装。这可以在 docker-compose.yml 中完成,如下所示:

  redis:
image:redis
worker:
build:./worker
命令:npm start
ports:
- 9730:9730
卷:
- worker /:/ worker /
- / worker / node_modules
links:
- redis
pre>

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



如果您想阅读有关卷的更多信息,可以在这里找到一个不错的用户指南:https://docs.docker.com/userguide/dockervolumes/


I have an app with the following services:

  • 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/

Now this question only concerns the 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

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>

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)

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

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.

What's going wrong here?

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

解决方案

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.

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.

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

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.

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

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

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