我是've been building a Node.js app on Docker, and following the advice in John Lees-Miller'用于设置环境的优秀Lessons from Building a Node App in Docker . 一切都工作正常一两个星期,但今天我开始遇到一个我无法弄清楚的问题 .
简而言之,我无法再通过 docker-compose up
运行应用程序;我为新添加的模块依赖项收到节点错误:
sfsftp_1 | module.js:327
sfsftp_1 | throw err;
sfsftp_1 | ^
sfsftp_1 |
sfsftp_1 | Error: Cannot find module 'eval'
sfsftp_1 | at Function.Module._resolveFilename (module.js:325:15)
sfsftp_1 | at Function.Module._load (module.js:276:25)
sfsftp_1 | at Module.require (module.js:353:17)
sfsftp_1 | at require (internal/module.js:12:17)
sfsftp_1 | at Object.<anonymous> (/home/app/sfsftp/lib/reformatter.js:4:13)
sfsftp_1 | at Module._compile (module.js:409:26)
sfsftp_1 | at Object.Module._extensions..js (module.js:416:10)
sfsftp_1 | at Module.load (module.js:343:32)
sfsftp_1 | at Function.Module._load (module.js:300:12)
sfsftp_1 | at Module.require (module.js:353:17)
但是,如果我运行bash shell:
docker-compose run --rm sfsftp /bin/bash
并使用 node sftp.js
从容器内启动节点应用程序,应用程序启动正常!
我最初今天早些时候使用模块 jsonminify
来解决这个问题,我最近在项目中添加了该模块 . 我相信自从做出改变以来,我已经两种方式运行应用程序( docker-compose up
和 docker-compose run
来自bash),但也许不是?为了方便起见,我决定解决这个问题,并在 jsonminify
上删除了我的用法 . 后来,我需要将 eval
模块添加到我的项目中,现在我得到了该模块的相同错误 . 我觉得 docker-compose up
命令使用的是图像的旧版本而不是 docker-compose run
命令,没有我最近的更改 .
当我按照文章中的过程进行操作时 - 使用 docker-compose run
获取bash shell并在正在运行的实例中运行 npm install --save module
. 我的 package.json
和 npm-shrinkwrap.json
文件正在更新,我在两者中都看到了 eval
模块 .
我仍然相当擅长开发Docker容器,所以我已经达到了“让我们试试这个”的意义 . 到目前为止我尝试过:
-
docker-compose build
后跟docker-compose up
-
docker-compose up --build
-
docker-compose build --no-cache
后跟docker-compose up
-
docker run -p 22:9001 sftpdocker_sfsftp
最后一个工作 - 直接运行docker,而不是通过docker-compose . 但这会失去设置的一些好处 . 如何使docker-compose工作?
供参考,这是我的 Dockerfile
:
# prepared with reference to http://jdlm.info/articles/2016/03/06/lessons-building-node-app-docker.html
# Current LTS Node version
FROM node:4.6.0
# Let's not run as Root. And, update to recent NPM
RUN useradd --user-group --create-home --shell /bin/false app &&\
npm install --global npm@3.7.5
ENV HOME=/home/app
# Get what we need for npm install
COPY package.json npm-shrinkwrap.json $HOME/sfsftp/
RUN chown -R app:app $HOME/*
# and install dependencies
USER app
WORKDIR $HOME/sfsftp
RUN npm install && npm cache clean
# do this after dependencies, so that if only the app changes, npm install won't be rerun
USER root
COPY . $HOME/sfsftp
RUN chown -R app:app $HOME/*
USER app
# Start it up!
CMD ["node", "sftp.js"]
和 docker-compose.yml
:
sfsftp:
build: .
ports:
- '22:9001'
volumes:
- .:/home/app/sfsftp
- /home/app/sfsftp/node_modules
最后, package.json
:
{
"name": "sftp2sf",
"version": "1.0.0",
"description": "",
"main": "sftp.js",
"scripts": {
"start": "node sftp.js",
"test": "mocha",
"coverage": "istanbul cover _mocha -- -R spec && open coverage/lcov-report/index.html"
},
"author": "Jason Clark <jason.clark@example.com>",
"license": "UNLICENSED",
"dependencies": {
"buffer-equal-constant-time": "^1.0.1",
"byline": "^5.0.0",
"eval": "^0.1.1",
"fast-csv": "^2.3.0",
"jsforce": "^1.7.0",
"jsonminify": "^0.4.1",
"minimatch": "^3.0.3",
"minimist": "^1.2.0",
"moment": "^2.15.1",
"ssh2": "^0.5.2",
"through": "^2.3.8"
},
"devDependencies": {
"chai": "^3.5.0",
"istanbul": "^0.4.5",
"mocha": "^3.1.0",
"sinon": "^1.17.6",
"stream-to-array": "^2.3.0"
}
}
Update: 要解决建议的解决方案,删除docker-compose.yml的卷部分:卷部分是此设置的重要部分,并允许我的本地主机在开发期间与正在运行的docker镜像共享文件,但node_modules除外只生活在图像中;请参阅链接文章以获取完整说明 . 从这个项目开始,我已经将这个设置与那些卷语句一起使用,并且至少有十几个其他Node模块以相同的方式安装,并且它们不会导致异常 - 如果我删除了 eval
,代码有效 .
Update 17 Nov 2016: 这似乎解决了自己;在将齿轮切换到优先级较高的项目几天后,我不再遇到问题 . 我不相信修复自己的错误,但我无法弄清楚我可能做了什么来解决这个问题 . 今天,我不得不在项目中添加一个新的节点模块( docker-compose -f docker-compose.yml run --rm sfsftp /bin/bash
,从运行的shell内部 npm install --save module
, docker-compose build
),现在问题又回来了,只有它是无法找到的新模块 .
3 回答
我遇到了同样的问题,发现解决办法是取出容器,然后重新启动,即
工作中的
docker run
中没有卷部分:我建议尝试模仿
docker-compose.yml
文件中的docker run
. 它正在删除卷部分 .如果删除卷部分有效,那么您在主机中拥有或遗漏的内容在安装时会导致问题 .
另外,我建议将文件升级到
version: '2'
. Docker组合对版本1文件表现得很奇怪 .希望能帮助到你
问题是compose文件中的
node_modules
卷被设置为匿名,在重新创建容器时会保留匿名卷,即使使用--build
,该节点仍然无法找到新添加的模块 . 请参阅问题here .现在,我使用这两个命令使其工作,因为docker-compose v1.9与--renew-anon-volumes巫婆我认为应该用来处理这种情况尚未正式发布: