npm ERR! 使离子服务命令失败(要求检查安装的node.js和npm的版本)

我正尝试用ionic framework2创build一个docker environement(我希望用于git和我的团队)。

我有一个名为ionic-boilerplate的项目目录。 在这个目录中,我有一个没有node_modules文件夹的离子应用程序。 当我执行docker-compose up –build命令时,在我的docker中,我安装了所有需要的depdancies。

这是我的离子样板/ Dockerfile

 FROM node:6.9.4 RUN npm install -g cordova@4.2.0 ionic@2.2.1 ENV DOCKER_CONTAINER_APP=/web-app RUN mkdir -p $DOCKER_CONTAINER_APP ADD . $DOCKER_CONTAINER_APP RUN cd $DOCKER_CONTAINER_APP WORKDIR $DOCKER_CONTAINER_APP RUN npm install EXPOSE 8100 35729 CMD ionic serve --all 

这是我的离子样板/ docker-compose.yml

 version: '2' services: ionic: build: . ports: - "8100:8100" - "35729:35729" volumes: - .:/web-app - ./node_modules:/web-app/node_modules 

当我启动命令docker-compose up --build或者docker-compose run ionic我有这个错误:

 Attaching to test_ionic_1 ionic_1 | npm info it worked if it ends with ok ionic_1 | npm info using npm@3.10.10 ionic_1 | npm info using node@v6.9.4 ionic_1 | npm info lifecycle ionic-hello-world@~preionic:serve: ionic-hello-world@ ionic_1 | npm info lifecycle ionic-hello-world@~ionic:serve: ionic-hello-world@ ionic_1 | ionic_1 | > ionic-hello-world@ ionic:serve /web-app ionic_1 | > ionic-app-scripts serve "--all" "--v2" "--address" "0.0.0.0" "--port" "8100" "--livereload-port" "35729" ionic_1 | ionic_1 | sh: 1: ionic-app-scripts: not found ionic_1 | ionic_1 | npm info lifecycle ionic-hello-world@~ionic:serve: Failed to exec ionic:serve script ionic_1 | npm ERR! Linux 4.4.0-59-generic ionic_1 | npm ERR! argv "/usr/local/bin/node" "/usr/local/bin/npm" "run" "ionic:serve" "--" "--all" "--v2" "--address" "0.0.0.0" "--port" "8100" "--livereload-port" "35729" ionic_1 | npm ERR! node v6.9.4 ionic_1 | npm ERR! npm v3.10.10 ionic_1 | npm ERR! file sh ionic_1 | npm ERR! code ELIFECYCLE ionic_1 | npm ERR! errno ENOENT ionic_1 | npm ERR! syscall spawn ionic_1 | npm ERR! ionic-hello-world@ ionic:serve: `ionic-app-scripts serve "--all" "--v2" "--address" "0.0.0.0" "--port" "8100" "--livereload-port" "35729"` ionic_1 | npm ERR! spawn ENOENT ionic_1 | npm ERR! ionic_1 | npm ERR! Failed at the ionic-hello-world@ ionic:serve script 'ionic-app-scripts serve "--all" "--v2" "--address" "0.0.0.0" "--port" "8100" "--livereload-port" "35729"'. ionic_1 | npm ERR! Make sure you have the latest version of node.js and npm installed. ionic_1 | npm ERR! If you do, this is most likely a problem with the ionic-hello-world package, ionic_1 | npm ERR! not with npm itself. ionic_1 | npm ERR! Tell the author that this fails on your system: ionic_1 | npm ERR! ionic-app-scripts serve "--all" "--v2" "--address" "0.0.0.0" "--port" "8100" "--livereload-port" "35729" ionic_1 | npm ERR! You can get information on how to open an issue for this project with: ionic_1 | npm ERR! npm bugs ionic-hello-world ionic_1 | npm ERR! Or if that isn't available, you can get their info via: ionic_1 | npm ERR! npm owner ls ionic-hello-world ionic_1 | npm ERR! There is likely additional logging output above. ionic_1 | ionic_1 | npm ERR! Please include the following file with any support request: ionic_1 | npm ERR! /web-app/npm-debug.log ionic_1 | There was an error serving your Ionic application: There was an error with the spawned command: serve test_ionic_1 exited with code 0 

Dockerfile 指令 CMD ionic serve Dockerfile发生错误。

同样的方法在本地没有docker,即使命令npm install然后ionic serve效果很好! 在哪里我的docker方法错了?

您的卷装载正在覆盖图像内容

你的形象是这样构build的:

 ENV DOCKER_CONTAINER_APP=/web-app WORKDIR $DOCKER_CONTAINER_APP RUN npm install 

但在运行时,docker-compose会这样做:

 volumes: - .:/web-app - ./node_modules:/web-app/node_modules 

因为您在/web-app上挂载了一个外部path,所以会覆盖该path中映像的所有内容。 这在开发过程中可能是有用的,但是有一个权衡:你需要在外部提供任何必要的path,因为图像本身不再可以。

有效地使用这些安装从Dockerfile反转这些步骤:

 ADD . $DOCKER_CONTAINER_APP RUN npm install 

选项1:在外部修复

一种select是在容器外运行npm install 。 如果使用所需的模块填充外部node_modules/ ,那么代码将很高兴,并且应该运行。

选项2:卸下支架

另一种方法是从docker-compose.yml中删除卷装载,并使用已经内置到映像中的代码。

这应该解决这个问题,代价是只有图像中已经存在的内容,而不能快速更新它。 在这种情况下,每次更改代码时都必须重新生成映像。

选项3:使用入口点脚本来做准备工作

您也可以使用在容器启动时执行npm install的entypoint脚本。

Dockerfile:

 ADD entrypoint.sh /entrypoint.sh ENTRYPOINT ["/entrypoint.sh"] 

entrypoint.sh

 #!/bin/sh npm install exec "$@" 

这将在开始时运行npm install ,然后从Dockerfile执行CMD

select哪个选项

这是挑选权衡的问题。 你现在拥有的东西在开发过程中是一种常见的模式。 由于代码被装载到容器中,因此可以快速迭代。 您更改代码,可能必须执行快速容器重新启动,并且新代码正在运行。 没有重build需要。

但是另一方面,你的应用程序需要的所有东西都必须在外部提供。

在发展过程中,国际海事组织,这是一个有用的权衡,因为你获得速度。 当需要部署应用程序时,通常会停止使用这些安装程序,并依赖于映像中的内容。 这样事情就更容易预测,而依赖关系也就更less了。

入口点脚本是两个世界中最好的,因为你可以保持坐骑,但仍然更新你的依赖关系。 不过,在启动过程中花费一点时间。

最后,我find另一种方法。 我删除了DockerFile中的RUN指令,然后像这样重写我的docker-compose.yml:

 version: '2' services: web: build: context: . environment: - NODE_ENV=development - DEBUG='true' ports: - 8100:8100 - 35729:35729 volumes: - .:/web-app - ./node_modules:/web-app/node_modules command: sh -c 'npm install; ionic serve --all' 

它像我期望的那样工作。 即安装npm包依赖并运行ionic serve命令。

不要犹豫,问我这是不是一个好习惯。