docker-compose up找不到模块,但是从bash运行

时间:2016-10-21 02:13:04

标签: node.js docker docker-compose

我一直在Docker上构建一个Node.js应用程序,并遵循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来解决这个问题,我最近已将其添加到项目中;我相信自从做出改变以来,我已经通过bash两种方式运行应用程序(docker-compose updocker-compose run,但也许不是?为了方便起见,我决定解决这个问题,并在jsonminify上删除了我的用法。后来,我需要将eval模块添加到我的项目中,现在我得到了该模块的相同错误。我觉得docker-compose up命令使用的是图像的旧版本而不是docker-compose run命令,没有我最近的更改。

当我添加模块时,我已经按照文章中的过程进行操作 - 使用docker-compose run获取bash shell并在正在运行的实例中运行npm install --save module。我的package.jsonnpm-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"
  }
}

更新:要解决建议的解决方案,请删除docker-compose.yml的卷部分:卷部分是此设置的重要部分,并允许我的本地主机共享文件在开发期间运行docker镜像,除了只存在于图像中的node_modules;请参阅链接文章以获取完整说明。从这个项目开始,我已经将这个设置用于那些卷语句是值得的,并且至少有十几个其他Node模块以相同的方式安装,并且它们不会导致异常 - 如果我删除{ {1}},代码有效。

2016年11月17日更新:这似乎已经解决了;在将齿轮切换到优先级较高的项目几天后,我不再遇到问题。我不相信修复自己的错误,但我无法弄清楚我可能做了什么来解决这个问题。今天,我不得不从正在运行的shell eval内部向项目添加一个新的节点模块(docker-compose -f docker-compose.yml run --rm sfsftp /bin/bashnpm install --save module,现在问题又回来了,只有它是新模块无法找到。

4 个答案:

答案 0 :(得分:15)

我遇到了同样的问题,发现解决办法是拆除容器,然后重新启动它,即

npm install some-package --save

docker-compose build

docker-compose down

docker-compose up

答案 1 :(得分:7)

问题是compose文件中的node_modules卷被设置为匿名,重新创建容器时会保留匿名卷,即使使用--build,该节点仍然无法找到新添加的模块。请参阅问题here

目前,我使用这两个命令使其工作,因为docker-compose v1.9 --renew-anon-volumes我认为应该用来处理这种情况的女巫尚未正式发布:

docker-compose down
docker-compose up --build

答案 2 :(得分:1)

工作的docker run中没有卷部分:

  volumes:
    - .:/home/app/sfsftp
    - /home/app/sfsftp/node_modules

我建议尝试模仿docker run文件中的docker-compose.yml。它正在删除卷部分。

如果删除卷部分有效,那么您在主机中拥有或遗漏的内容在安装时会导致问题。

另外,我建议您将文件升级到version: '2'。 Docker组合对版本1文件表现得很奇怪。

希望有所帮助

答案 3 :(得分:0)

就我而言,docker-compose down 没有帮助,所以我需要手动删除该卷。

使用 docker volume ls 列出所有卷 然后 docker volume rm $VOLUME_ID 删除 anonymous

此外,您应该命名您的 node_modules 卷,这样它就会列在 docker volume ls

services: 
  sfsftp:
    ...
    volumes:
      - .:/home/app/sfsftp
      - node_modules:/home/app/sfsftp/node_modules

volumes:
  node_modules: