为啥 COPY package*.json ./ 在 COPY 之前。 .?

Posted

技术标签:

【中文标题】为啥 COPY package*.json ./ 在 COPY 之前。 .?【英文标题】:Why COPY package*.json ./ precedes COPY . .?为什么 COPY package*.json ./ 在 COPY 之前。 .? 【发布时间】:2019-01-03 03:09:53 【问题描述】:

在这个关于 Docker 的 Node.js 教程中: https://nodejs.org/en/docs/guides/nodejs-docker-webapp/

COPY package*.json ./ 的意义何在?

不是全部都用COPY . .复制了吗?

有问题的 Dockerfile:

FROM node:8

# Create app directory
WORKDIR /usr/src/app

# Install app dependencies
# A wildcard is used to ensure both package.json AND package-lock.json are copied
# where available (npm@5+)
COPY package*.json ./

RUN npm install
# If you are building your code for production
# RUN npm install --only=production

# Bundle app source
COPY . .

EXPOSE 8080
CMD [ "npm", "start" ]

【问题讨论】:

如果您将RUN npm install 放在COPY . . 下,我很确定删除COPY package*.json ./ 仍然有效。同样的问题,我认为没有必要...... COPY package*.json 是否也包含 packge-lock.json 文件?如果不是,那么星星是什么? 【参考方案1】:

这是 Dockerfiles(所有语言)中的常见模式。 npm install 步骤耗时较长,但只需要在包依赖发生变化时运行即可。因此,通常会看到一个步骤只是安装依赖项,而第二步是添加实际应用程序,因为它可以更快地重建容器。

你是对的,如果你只构建一次图像,这本质上是相同的;最后你会得到相同的文件系统内容。

不过,假设您在处理软件包时会发生这种情况。您更改了一些src/*.js 文件,但没有更改package.json。你运行npm test,它看起来不错。现在你重新运行docker build。 Docker 注意到 package*.json 文件没有改变,所以它使用它第一次构建的相同镜像层而不重新运行任何东西,它也跳过了npm install 步骤(因为它假设在相同的输入文件系统上运行相同的命令会产生相同的输出文件系统)。所以这使得 second 构建运行得更快。

【讨论】:

我认为这是一种偷工减料,提供npm installfails,我们避免继续复制应用程序源。 但是在第一层创建的node_modules 目录不是被下一层的node_modules 目录完全覆​​盖了吗?此外,理论上主机目录中可能有更新的模块版本,package.json 不变。 您还应该在.dockerignore 文件中包含node_modules,这样COPY 步骤就不会覆盖刚刚得到的npm installed。

以上是关于为啥 COPY package*.json ./ 在 COPY 之前。 .?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我们需要使用 package.json? [复制]

为啥 `npm install` 会为同一个 `package.json` 文件生成不同的 `package-lock.json` 文件?

如何使用Dockerfile中的单个COPY层复制不同源和目标目录中的多个文件

为啥不通过 package.json 安装 webpack 二进制文件?

为啥我可以将脚本添加到 package.json 中的脚本? [关闭]

为啥 npm 试图在错误的目录中找到 package.json?