docker 如何构建Docker文件时缓存RUN npm安装指令
简介
在构建Docker镜像时,最耗费时间和资源的步骤之一是运行 “RUN npm install “指令。这个指令会安装package.json文件中列出的所有依赖项。缓存这个指令的结果可以大大改善你的图像的构建时间。在这篇文章中,我们将探讨在Docker文件中缓存 “RUN npm install “指令的不同策略。
缓存策略
在Docker文件中缓存 “RUN npm install “指令有几种策略。这些策略包括
- 使用.dockerignore文件 – 这个策略涉及排除node_modules目录被复制到镜像中。这是通过创建一个.dockerignore文件并在其中列出node_modules目录来实现的。当镜像被构建时,node_modules目录下的文件不会被复制,”RUN npm install “指令会被再次执行。这种策略实现起来很简单,但它有一个缺点,那就是增加了镜像的大小,因为它将包含所有的依赖关系。
-
多阶段构建 – 这种策略涉及在Docker文件中使用多个FROM语句来创建多个镜像,每个镜像都有特定的目的。构建的第一阶段安装依赖项并复制node_modules目录。第二阶段的构建只复制第一阶段的必要文件,如应用程序代码。这种策略减少了镜像的大小,但它的设置和维护可能更复杂。
-
使用锁包文件– 这种策略包括使用锁包文件,如npm-shrinkwrap.json或yarn.lock,以确保安装的一致性。这些文件锁定了依赖关系的版本,这样每次构建镜像时都会安装相同的版本。这种策略实现起来很简单,有助于确保一致性,但如果依赖关系更新了,而锁文件没有更新,就会导致问题。
-
使用npm缓存卷– 这种策略涉及为npm缓存创建一个卷,并将其用于 “RUN npm install “指令。这将使npm安装更快,因为软件包已经被缓存了,但它需要额外的配置和对卷的管理。
-
使用BuildKit – BuildKit是Docker 18.09版本中增加的一项功能,可以提高构建性能。它允许在多个阶段和镜像中缓存npm包,减少npm安装指令的时间。
-
使用–no-cache标志– 这种策略涉及在 “RUN npm install “指令中使用–no-cache标志,它告诉Docker在运行该指令时不使用缓存。如果缓存有问题或者依赖关系已经更新,这可能很有用。然而,这将增加构建的时间。
在Docker文件中实现缓存
下面是如何在Docker文件中实现上面讨论的一些策略的例子 —
- 使用一个.dockerignore文件 –
# .dockerignore file
node_modules
# Dockerfile
COPY . .
RUN npm install
- 多阶段的建设 –
# Dockerfile
FROM node:12 as builder
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM node:12
COPY --from=builder node_modules node_modules
COPY --from=builder dist dist
CMD ["npm", "start"]
- 使用包锁文件– -
# package-lock.json or yarn.lock file
...
# Dockerfile
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
- 使用npm缓存卷 –
# Dockerfile
VOLUME /root/.npm
COPY package.json package-lock.json ./
RUN npm ci --cache /root/.npm
COPY . .
- 使用BuildKit –
# Dockerfile
COPY package.json package-lock.json ./
RUN --mount=type=cache,target=/root/.npm npm ci
COPY . .
- 使用–no-cache标志- -
# Dockerfile
COPY package.json package-lock.json ./
RUN npm ci --no-cache
COPY . .
在Docker中缓存RUN npm安装指令的最佳实践
- 使用包锁文件(如npm-shrinkwrap.json或yarn.lock),以确保一致的安装和锁定依赖的版本。
-
使用多阶段构建,只从之前的构建中复制必要的文件,如node_modules目录,这可以帮助减少镜像的大小。
-
使用.dockerignore文件来排除node_modules目录被复制到镜像中,这可以帮助加快构建时间,但它会增加镜像的大小。
-
使用npm缓存卷,在多个阶段和镜像中缓存npm包,减少npm安装指令的时间。
-
使用BuildKit,这是在Docker 18.09版本中增加的一个功能,可以提高构建性能,并允许在多个阶段和镜像中缓存npm包。
-
谨慎使用–no-cache标志,因为它告诉Docker在运行指令时不使用缓存,而且会增加构建的时间。
-
定期监控缓存,检查缓存,必要时清除缓存,如果你发现缓存没有按照预期工作。
-
保持你的依赖关系是最新的,如果你使用的是包锁文件,确保相应的更新锁文件。
-
始终在启用和禁用缓存的情况下测试你的构建,以确保缓存按预期工作。
-
考虑使用一个单独的容器或服务来处理npm安装步骤,这可以帮助加快构建过程,并确保多个构建的一致性。
总结
缓存Docker文件中的 “RUN npm install “指令可以大大改善镜像的构建时间。有几种缓存策略,包括使用.dockerignore文件、多阶段构建、包锁文件、npm缓存卷、BuildKit和–no-cache标志。每种策略都有自己的优点和缺点,对你的使用情况来说,最佳策略取决于你的具体要求。为了排除故障和维护缓存,你可以使用Docker缓存命令并在需要时清除缓存。