【问题标题】:npm ERR! Failed when make ionic serve command (ask for checking version of node.js and npm installed)npm 错误! make ionic serve 命令失败(要求检查 node.js 和 npm 安装的版本)
【发布时间】:2017-01-19 23:59:44
【问题描述】:

我正在尝试使用 ionic 框架 2 创建一个 docker 环境(我希望与 git 和我的团队一起使用)。

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

这是我的 ionic-boilerplate/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

这是我的ionic-boilerplate/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 --builddocker-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

在没有 docker 的情况下在本地使用相同的方法,即使命令 npm install 然后 ionic serve 运行良好! docker方法我哪里错了?

【问题讨论】:

  • RUN cd ...WORKDIR 是多余的,或者更准确地说,RUN 完全没有任何作用,应该被删除。只保留WORKDIR
  • @DanLowe 谢谢你,我确实忘记删除这个命令了。

标签: javascript node.js docker ionic-framework docker-compose


【解决方案1】:

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

您的图像是这样构建的:

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 上安装了一个外部路径,它会覆盖该路径中内置于映像中的所有内容。这在开发过程中可能很有用,但有一个权衡:您需要在路径上从外部提供任何必要的东西,因为图像本身不再可以。

使用这些挂载可以有效地逆转 Dockerfile 中的这些步骤:

ADD . $DOCKER_CONTAINER_APP
RUN npm install

选项 1:外部修复

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

选项 2:移除支架

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

这应该可以解决问题,但代价是只有图像中已有的内容,并且无法快速更新它。在这种情况下,每次更改代码时都必须重新构建映像。

选项 3:使用入口点脚本进行准备工作

您还可以使用在容器启动时执行npm install 的实体点脚本。

Dockerfile:

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

entrypoint.sh

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

这将在启动时运行 npm install,然后从 Dockerfile 执行 CMD

选择哪个选项

这是选择权衡的问题。您现在拥有事物的方式是开发过程中的常见模式。因为代码是挂载到容器中的,所以可以快速迭代。您更改了代码,可能需要快速重启容器,并且新代码正在运行。无需重建。

但另一方面,您的应用所需的一切都必须由外部提供。

在开发过程中,IMO,这是一个有用的权衡,因为您获得了速度。在部署应用程序时,您通常会停止使用这些挂载并依赖映像中的内容。这样一来,事情就更可预测了,并且依赖项/可能出错的事情更少。

入口点脚本是两全其美的,因为您可以保留挂载,但仍会更新您的依赖项。不过,在启动过程中确实会花费一些时间。

【讨论】:

  • 我知道 docker 在构建时安装了 ./node_modules ,并且其中没有依赖关系。这里的目的是不在容器外运行 npm install 。您是否有建议在容器内创建 npm install 命令,然后与所有依赖项共享 node_modules 文件夹?顺便谢谢你的回答。
  • @french_dev 如果你想使用容器内置的模块而不是依赖外部资源,那么移除两个挂载。我已经用更长的解释更新了我的答案。
  • @french_dev .. 刚刚使用入口点脚本添加了另一个更新,这是我经常使用的东西。
  • 您通过添加入口点的建议比我预期的要好,我按照您的指示进行操作,它就像一个魅力!谢谢。
  • @french_dev 只是为了明确一点,使用入口点,您不再需要 docker-compose.yml 中的command:
【解决方案2】:

最后,我找到了另一种方法。我删除了 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 命令。

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

【讨论】:

    猜你喜欢
    • 2021-10-28
    • 2011-10-02
    • 1970-01-01
    • 2013-01-24
    • 1970-01-01
    • 2015-12-23
    • 1970-01-01
    • 2016-10-01
    相关资源
    最近更新 更多