KGo*_*KGo 155 node.js docker ubuntu-14.04 docker-compose
我有一个具有以下服务的应用程序:
web/
- 在端口5000上保存并运行python 3 flask Web服务器.使用sqlite3.worker/
- 有一个index.js
文件,它是队列的工作者.Web服务器使用json API over port与此队列交互9730
.工人使用redis进行存储.工作人员还将数据本地存储在文件夹中worker/images/
现在这个问题只涉及到了worker
.
worker/Dockerfile
FROM node:0.12
WORKDIR /worker
COPY package.json /worker/
RUN npm install
COPY . /worker/
Run Code Online (Sandbox Code Playgroud)
docker-compose.yml
redis:
image: redis
worker:
build: ./worker
command: npm start
ports:
- "9730:9730"
volumes:
- worker/:/worker/
links:
- redis
Run Code Online (Sandbox Code Playgroud)
当我运行时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>
Run Code Online (Sandbox Code Playgroud)
但是当我这样做时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)
Run Code Online (Sandbox Code Playgroud)
事实证明/worker/node_modules
(主机或容器中)没有任何模块存在.
如果在主机上,我npm install
,那么一切正常.但我不想这样做.我希望容器处理依赖项.
这里出了什么问题?
(不用说,所有包都在package.json
.)
Fre*_*kNS 227
发生这种情况是因为您已将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
Run Code Online (Sandbox Code Playgroud)
我不完全确定这是否会对图像的可移植性造成任何问题,但由于您似乎主要使用docker来提供运行时环境,因此这应该不是问题.
如果您想了解更多有关卷的信息,可以在此处找到一个很好的用户指南:https://docs.docker.com/userguide/dockervolumes/
jsa*_*san 31
卷node_modules
将覆盖该文件夹,并且容器中不再可访问该文件夹.我正在使用本机模块加载策略从卷中取出文件夹:
/data/node_modules/ # dependencies installed here
/data/app/ # code base
Run Code Online (Sandbox Code Playgroud)
Dockerfile:
COPY package.json /data/
WORKDIR /data/
RUN npm install
ENV PATH /data/node_modules/.bin:$PATH
COPY . /data/app/
WORKDIR /data/app/
Run Code Online (Sandbox Code Playgroud)
node_modules
无法从容器外部访问,因为它包含在图像中.
Gui*_*ent 29
@FrederikNS提供的解决方案有效,但我更喜欢显式命名我的node_modules卷.
我的project/docker-compose.yml
文件(docker-compose版本1.6+):
version: '2'
services:
frontend:
....
build: ./worker
volumes:
- ./worker:/worker
- node_modules:/worker/node_modules
....
volumes:
node_modules:
Run Code Online (Sandbox Code Playgroud)
我的文件结构是:
project/
??? worker/
? ?? Dockerfile
??? docker-compose.yml
Run Code Online (Sandbox Code Playgroud)
它会创建一个名为的卷,project_node_modules
并在每次启动应用程序时重新使用它.
我docker volume ls
看起来像这样:
DRIVER VOLUME NAME
local project1_mysql
local project1_node_modules
local project2_postgresql
local project2_node_modules
Run Code Online (Sandbox Code Playgroud)
小智 20
我最近有类似的问题.您可以node_modules
在其他地方安装并设置NODE_PATH
环境变量.
在下面的例子中我安装node_modules
了/install
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/
Run Code Online (Sandbox Code Playgroud)
redis:
image: redis
worker:
build: ./worker
command: npm start
ports:
- "9730:9730"
volumes:
- worker/:/worker/
links:
- redis
Run Code Online (Sandbox Code Playgroud)
hol*_*lms 16
有优雅的解决方案:
只是挂载不是整个目录,而只是挂载app目录.这样你就不会有麻烦了npm_modules
.
例:
frontend:
build:
context: ./ui_frontend
dockerfile: Dockerfile.dev
ports:
- 3000:3000
volumes:
- ./ui_frontend/src:/frontend/src
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
JAM*_*JAM 13
我遇到了同样的问题.当文件夹/worker
安装到容器时 - 它的所有内容都将同步(因此如果你没有本地文件,node_modules文件夹将会消失.)
由于基于操作系统的不兼容的npm软件包,我不能只在本地安装模块 - 然后启动容器,所以..
我的解决方案是将源包装在一个src
文件夹中,然后node_modules
使用这个index.js文件链接到该文件夹.因此,该index.js
文件现在是我的应用程序的起点.
当我运行容器时,我将/app/src
文件夹挂载到我的本地src
文件夹.
所以容器文件夹看起来像这样:
/app
/node_modules
/src
/node_modules -> ../node_modules
/app.js
/index.js
Run Code Online (Sandbox Code Playgroud)
它很难看,但它有效..
由于Node.js加载模块的方式,node_modules
可以在源代码的路径中的任何位置.例如,把你的源头/worker/src
的和package.json
在/worker
,所以/worker/node_modules
是他们安装位置.
将容器中的node_modules安装到与项目文件夹不同的位置,并将NODE_PATH设置为node_modules文件夹有助于我(你需要重建容器).
我正在使用docker-compose.我的项目文件结构:
-/myproject
--docker-compose.yml
--nodejs/
----Dockerfile
Run Code Online (Sandbox Code Playgroud)
泊坞窗,compose.yml:
version: '2'
services:
nodejs:
image: myproject/nodejs
build: ./nodejs/.
volumes:
- ./nodejs:/workdir
ports:
- "23005:3000"
command: npm run server
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
我看到节点开发环境有两个单独的要求...将源代码安装到容器中,然后从容器中安装node_modules(对于您的IDE)。为了完成第一个任务,你需要进行通常的安装,但不是所有的事情......只是你需要的东西
volumes:
- worker/src:/worker/src
- worker/package.json:/worker/package.json
- etc...
Run Code Online (Sandbox Code Playgroud)
(不这样做的原因- /worker/node_modules
是因为 docker-compose 将在运行之间保留该卷,这意味着您可能会偏离映像中的实际内容(违背了不仅仅是从主机绑定安装的目的))。
第二个其实更难。我的解决方案有点黑客,但它有效。我有一个脚本用于在主机上安装 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
Run Code Online (Sandbox Code Playgroud)
还有一些简单的解决方案,没有将node_module
目录映射到另一个卷.它将把npm软件包安装到最终的CMD命令中.
这种方法的缺点:
- 运行
npm install
每次运行容器(从开关npm
到yarn
也可能会加速这一进程中位).
FROM node:0.12
WORKDIR /worker
COPY package.json /worker/
COPY . /worker/
CMD /bin/bash -c 'npm install; npm start'
Run Code Online (Sandbox Code Playgroud)
redis:
image: redis
worker:
build: ./worker
ports:
- "9730:9730"
volumes:
- worker/:/worker/
links:
- redis
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
69581 次 |
最近记录: |