Docker构建Dockerfile时如何缓存RUN npm install指令?


简介

构建Docker镜像时,最耗时和资源密集的步骤之一是运行“RUN npm install”指令。此指令会安装package.json文件中列出的所有依赖项。缓存此指令的结果可以大大缩短镜像的构建时间。在本文中,我们将探讨在Dockerfile中缓存“RUN npm install”指令的不同策略。

缓存策略

在Dockerfile中缓存“RUN npm install”指令有几种策略,包括:

  • 使用.dockerignore文件 − 此策略包括将node_modules目录排除在复制到镜像之外。这是通过创建一个.dockerignore文件并在其中列出node_modules目录来实现的。构建镜像时,不会复制node_modules目录中的文件,并且会再次执行“RUN npm install”指令。此策略易于实现,但有一个缺点,即它会增加镜像的大小,因为它将包含所有依赖项。

  • 多阶段构建 − 此策略包括在Dockerfile中使用多个FROM语句来创建多个镜像,每个镜像都有特定的用途。构建的第一阶段安装依赖项并复制node_modules目录。构建的第二阶段仅复制第一阶段的必要文件,例如应用程序代码。此策略减小了镜像的大小,但设置和维护起来可能更复杂。

  • 使用package-lock文件 − 此策略包括使用package-lock文件(例如npm-shrinkwrap.json或yarn.lock)来确保一致的安装。这些文件锁定依赖项的版本,以便每次构建镜像时都安装相同的版本。此策略易于实现,并有助于确保一致性,但如果依赖项更新而锁定文件未更新,则可能会导致问题。

  • 使用npm缓存卷 − 此策略包括为npm缓存创建一个卷,并将其用于“RUN npm install”指令。由于软件包已缓存,这将使npm install更快,但需要额外配置和管理卷。

  • 使用BuildKit − BuildKit是Docker 18.09版本中添加的一项功能,可提高构建性能。它允许跨多个阶段和镜像缓存npm软件包,从而减少npm install指令的时间。

  • 使用--no-cache标志 − 此策略包括在“RUN npm install”指令中使用--no-cache标志,该标志告诉Docker在运行命令时不要使用缓存。如果缓存存在问题或依赖项已更新,这将很有用。但是,这会增加构建时间。

在Dockerfile中实现缓存

以下是如何在Dockerfile中实现上述一些策略的示例:

  • 使用.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文件

# 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 install指令的最佳实践

  • 使用package-lock文件(例如npm-shrinkwrap.json或yarn.lock)来确保一致的安装并锁定依赖项的版本。

  • 使用多阶段构建仅复制前一个构建的必要文件(例如node_modules目录),这有助于减小镜像的大小。

  • 使用.dockerignore文件将node_modules目录排除在复制到镜像之外,这有助于加快构建时间,但可能会增加镜像的大小。

  • 使用npm缓存卷来跨多个阶段和镜像缓存npm软件包,从而减少npm install指令的时间。

  • 使用BuildKit,这是Docker 18.09版本中添加的一项功能,它可以提高构建性能并允许跨多个阶段和镜像缓存npm软件包。

  • 谨慎使用--no-cache标志,因为它会告诉Docker在运行命令时不要使用缓存,并且会增加构建时间。

  • 定期监控缓存,检查缓存并在必要时清除缓存,如果您发现缓存无法按预期工作。

  • 保持您的依赖项更新,如果您使用package-lock文件,请确保相应地更新锁定文件。

  • 始终在启用和禁用缓存的情况下测试您的构建,以确保缓存按预期工作。

  • 考虑使用单独的容器或服务来处理npm install步骤,这有助于加快构建过程并确保跨多个构建的一致性。

结论

在Dockerfile中缓存“RUN npm install”指令可以大大缩短镜像的构建时间。有几种缓存策略,包括使用.dockerignore文件、多阶段构建、package-lock文件、npm缓存卷、BuildKit和--no-cache标志。每种策略都有其自身的优缺点,最适合您的用例的策略将取决于您的特定需求。要对缓存进行故障排除和维护,您可以使用Docker缓存命令并在需要时清除缓存。

更新于:2023年2月17日

8K+ 浏览量

开启您的职业生涯

通过完成课程获得认证

开始
广告