我有一个具有以下服务的应用程序:
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 许可协议
发生这种情况是因为您已将
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
中完成,如下所示:我不完全确定这是否会对图像的可移植性造成任何问题,但由于您似乎主要使用 docker 来提供运行时环境,所以这应该不是问题。
如果你想阅读更多关于卷的信息,这里有一个很好的用户指南: https ://docs.docker.com/userguide/dockervolumes/
编辑:从那以后,Docker 改变了它的语法,要求前导
./
用于安装在与 docker-compose.yml 文件相关的文件中。