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

问题描述 投票:0回答:4

在这个关于 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" ]
node.js docker
4个回答
70
投票

这是 Dockerfile(所有语言)中的常见模式。

npm install
步骤需要很长时间,但您只需要在包依赖项发生变化时运行它。 因此,通常会看到一个步骤仅安装依赖项,第二个步骤添加实际应用程序,因为它使重建容器变得更快。

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

假设这种情况发生在您处理包裹时。 您更改了一些

src/*.js
文件,但尚未更改
package.json
。 你运行
npm test
,看起来不错。 现在您重新运行
docker build
。 Docker 注意到
package*.json
文件没有更改,因此它使用第一次构建的相同图像层,而无需重新运行任何内容,并且它还跳过
npm install
步骤
(因为它假设运行相同的命令在同一输入文件系统上会产生相同的输出文件系统)。 所以这使得第二个构建运行得更快。


2
投票

在构建镜像期间,docker 基于基于层的架构工作,即您在 Dockerfile 中写入的每一行都会进入该层并被缓存...现在首先复制

package*.json
文件的目的是一种优化您在构建映像期间在 Dockerfile 中执行的操作,如果我们想仅在将某些依赖项添加到项目中时运行命令
npm install
,因此将第一个 package*.json 复制到映像文件系统中,以便每个后续构建运行 npm install只有当一个新的依赖项被添加到项目中,然后将所有内容复制到图像文件系统中,然后在 docker 是一个无头软件之后,它不会检查层更改后的层,它只是在之后执行......因此,在将整个主机文件系统复制到映像文件系统后,我们每次都可以保存,而无需运行 npm install


1
投票

我们首先复制 package.json 和 package-lock.json 并在复制应用程序的其余部分之前安装依赖项的原因是速度和优化。

Docker 的镜像被集成到层中,Dockerfile 中的每一行代表一个层。当您构建镜像时,Docker 仅通过重建已更改的层以及顶部的层(在 Dockerfile 中找到的层)来尝试加快构建时间。

如果我们在安装依赖项之前复制整个代码库,那么在 Docker 开发期间所做的每次更改都必须重新安装所有单元,尽管大多数时候它们没有更改。而 Docker 只会执行 NPM 安装,如果你的包。 JSON 或 package-lock.json 已更改。如果没有,您将只复制代码库中的最新更改。

构建图像可能需要一些时间,因此这是我们想要使用的健康优化。


0
投票

这是一个非常好的问题。 Docker 为每个命令创建层。在构建时,docker 将看到更改,如果在某个层中检测到更改,则所有下面的层都将被重建。

例如,假设我们的 Dockerfile:

WORKDIR /app
COPY . /app
RUN npm install

而且我们会非常频繁地更改源代码,那么每次更改 docker 都会执行

npm install
。这是非常糟糕而且效率低下的。因为对于每一个小更改,我们都会重新安装整个
node.js
软件包(如果您不使用卷或缓存,则将需要很长时间)。

在这种情况下:

WORKDIR /app
COPY package.json /app
RUN npm install
COPY . /app

仅当 package.json 发生变化时,我们才会执行

npm install

© www.soinside.com 2019 - 2024. All rights reserved.