为什么在使用 npm install 时,package-lock.json 会导致 docker 容器构建失败?

Ege*_*Ege 5 node.js npm docker package-lock.json

网上有很多人用不同的方式问同样的问题,但没有明确的答案。任何人都可以理解到足以解释为什么docker buildpackage-lock.json应用程序中存在文件时会失败,而当文件不存在时会成功运行吗?貌似跟npm有关,但是不清楚。

每个人都说删除package-lock.json,但它存在是有原因的。

注意: npm install在我的本地机器上工作正常,只是在 docker 容器中失败。

如果我有这个 Dockerfile:

# First Stage: Builder
FROM node:13.12.0-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
Run Code Online (Sandbox Code Playgroud)

并运行这个:

docker build -t container-tag ./
Run Code Online (Sandbox Code Playgroud)

我明白了:

npm WARN tar ENOENT: no such file or directory, open '/app/node_modules/.staging/eventsource-c2615740/example/index.html'
npm WARN tar ENOENT: no such file or directory, open '/app/node_modules/.staging/eventsource-c2615740/example/sse-client.js'
npm WARN tar ENOENT: no such file or directory, open '/app/node_modules/.staging/react-router-a14663ae/README.md'
Run Code Online (Sandbox Code Playgroud)

但是这个 Dockerfile 会成功运行:

# First Stage: Builder
FROM node:13.12.0-alpine AS build
WORKDIR /app
COPY package.json ./       #<-------- note that there is no start here
RUN npm install
COPY . .
RUN npm run build
Run Code Online (Sandbox Code Playgroud)

Ict*_*tus 8

从你的问题:

注意:npm install 在我的本地机器上运行良好,只是在 docker 容器中失败

如果您正在使用npm install,您不确定具有相同版本的依赖项。

为了拥有可重现的环境,不会因依赖项的不同版本而出现意外问题,您宁愿使用npm ci

此命令类似于npm-install,不同之处在于它旨在用于自动化环境,例如测试平台、持续集成和部署 - 或者您希望确保对依赖项进行全新安装的任何情况。通过跳过某些面向用户的功能,它可以比常规的 npm 安装快得多。它也比常规安装更严格,可以帮助捕获由大多数 npm 用户增量安装的本地环境引起的错误或不一致。

简而言之,使用 npm install 和 npm ci 的主要区别是:

  • 该项目必须有一个现有的package-lock.jsonnpm- shrinkwrap.json
  • 如果包锁中的依赖项与package.json中的依赖项不匹配,npm ci将退出并显示错误,而不是更新包锁。
  • npm ci一次只能安装整个项目:无法使用此命令添加单个依赖项。
  • 如果node_modules已经存在,它将在npm ci开始安装之前自动删除。
  • 它永远不会写入package.json或任何包锁:安装基本上是冻结的。

费边甘德的文章中给出了进一步澄清有关npm installnpm ci工具,并提供有关何时使用每一个建议。下表来自该来源:

  cases                                | npm install | npm ci
 --------------------------------------|-------------|-------------
  needs package.json                   | no          | yes
  needs package-lock.json              | no          | yes
  installs from package.json           | yes         | no
  installs from package-lock.json      | no          | yes
  compares both                        | no          | yes
  updates loose package versions       | yes         | no
  updates loose dependencies           | yes         | no
  writes to package.json               | yes         | no
  writes to package-lock.json          | yes         | no
  deletes node_modules before install  | no          | yes
  used for installing separate package | yes         | no
  should be used on build systems / CI | no          | yes
  can be used for development          | yes         | yes
  reproducible installs                | no          | yes
Run Code Online (Sandbox Code Playgroud)

这就是package-lock.json存在的原因,可用于 npm ci.

在拥有可重现的环境后,如果这不能解决您的问题,您需要继续调查,但 IMO 应该是第一步。