Docker BuildKit 怎样复用构建缓存
Docker BuildKit 复用构建缓存有两条不同路径:输入没变时复用已完成的构建层;安装步骤需要重跑时,用 cache mount 保留包管理器下载缓存。要减少重复依赖下载,先把依赖清单复制放在源码复制之前,再把缓存挂载到包管理器实际使用的目录。两者可以一起使用,但不能混为一谈。
官方地址:https://docs.docker.com/build/cache/。下面以已有 package.json、package-lock.json 和 server.js 的 Node.js 项目为例,使用 Docker Desktop 的 Linux 容器构建环境。示例与配图仅供操作说明,没有实际运行或速度测试;不会承诺固定加速倍数。
1. 确认当前构建器,避免每次换一个缓存位置
在 Docker Desktop Dashboard 左侧点击 Builds,查看右上角显示的当前 builder 名称。需要了解构建器时,点击 Builder settings,进入 Settings 的 Builder 页面,确认使用的构建器正在运行。这里先观察,不删除历史、不清理缓存,也不为了教程切换团队共享环境。
Builds 中只有活动、运行中的构建器记录可见;Windows 容器的旧构建器记录不属于这个 BuildKit 视图。如果机器只装命令行工具,也可以使用下面的只读命令查看,后续 UI 步骤则不适用:
# 查看已有构建器及当前选择,不创建、不删除构建器
docker buildx ls
记下后续准备使用的构建器名称。不同 builder 的本地缓存彼此独立,换构建器后的首次构建不能直接拿来证明缓存配置无效。界面中能看到目标 builder,命令行也确认选择相同,才进入下一步。

2. 给依赖安装步骤挂载下载缓存
在项目编辑器的资源管理器中打开项目根目录 Dockerfile;没有时通过 New File 新建。将安装依赖步骤放到 COPY 源码之前。下面是独立示例,基础镜像版本要按项目支持范围选择;生产发布还应按团队策略固定镜像摘要。
# syntax=docker/dockerfile:1
# 选择项目支持的 Node.js 版本;此处作为演示基础镜像
FROM node:22-bookworm-slim
WORKDIR /srv/cache-demo
# 先复制依赖描述,普通源码变化不会直接影响这一步
COPY package.json package-lock.json ./
# 缓存 npm 下载内容;id 区分用途,locked 选择保守的串行访问
RUN --mount=type=cache,id=cache-demo-npm,target=/root/.npm,sharing=locked npm ci
# 安装产物留在 /srv/cache-demo/node_modules,而不是缓存挂载目录
COPY . .
# 使用项目实际入口,不在本文运行服务
CMD ["node", "server.js"]
这个镜像安装阶段以 root 用户运行,所以使用 /root/.npm。若基础镜像或 USER 指令改成其他用户,应按该用户的实际 npm cache 位置与写入权限调整 target;不能见到“npm 缓存”就固定抄 root 路径。
id 是缓存命名空间,不是保密或权限边界。sharing=locked 让共用该缓存的并发写入等待,适合保守起步,但可能降低并行吞吐;包管理器是否需要独占访问,要按其自身约束决定。
再打开根目录 .dockerignore,排除不应进入上下文的本地文件。不要将锁文件排除,否则 npm ci 缺少输入。
# 防止本机安装产物覆盖容器里安装的依赖
node_modules
# 不发送仓库历史和本地环境文件;项目若确需非敏感配置,应单独评估
.git
.env
.env.*
# 忽略调试日志,避免无关变化扩大上下文
npm-debug.log*
保存 Dockerfile 与 .dockerignore 后,检查编辑器的文件标签没有未保存标记,并确认 COPY 清单位于安装步骤之前,安装步骤位于 COPY . . 之前。这是配置完成的可见状态,不代表已经命中缓存。

3. 构建后区分层命中和下载缓存复用
读者可在项目根目录执行下面的构建命令,它会产生本地镜像;请使用自己的演示项目和已确认的构建器。本文不启动命令、不生成实测日志:
# 用当前构建器构建,输出详细日志并把结果加载到本地镜像库
docker buildx build --progress=plain --load -t cache-demo:local .
构建结束后,在 Docker Desktop → Builds → Build history 选择对应记录,打开 Info 查看 Cache usage,再打开 Logs,使用 List view 展开依赖安装步骤;需要完整文本时切换 Plain-text view。记录应显示成功,失败时先看 Error 标签对应的指令,不把错误归为缓存失效。
有两种不同观察:不改输入重复构建,依赖安装层可能显示 CACHED,意味着没有重新执行 npm ci;改了锁文件使安装步骤重新执行,下载缓存才有机会帮助复用已有包。第二种不能靠 CACHED 标签证明,也不能只凭总耗时变短推断没有下载。要结合包管理器日志、网络请求与实际输入判断,不写死日志格式或命中比例。
一个低风险对照是先只改 server.js 的无功能影响注释,再构建,观察依赖安装是否仍复用;另一组在独立分支中正常更新依赖及锁文件,再观察安装步骤。不要手工破坏 package-lock.json 只为强制重跑,也不要在生产构建器上删除缓存做对照。

CI 重建机器时,还要考虑另一种缓存
本地 builder 的缓存挂载不是镜像内容,也不应成为正确构建的必需输入。缓存可能被垃圾回收,构建仍须能从依赖清单重新获取内容。不要把源码、唯一产物或凭据保存在缓存挂载里;私有仓库认证需要独立的 secret 机制。
临时 CI 机器每次创建新的 builder,原来的本地缓存自然不在。外部缓存通过 cache-to 与 cache-from 导出和导入构建缓存,但不能因此假设普通缓存挂载目录也自动跨机器恢复。后端类型和缓存挂载持久化方式要单独确认,尤其不要把构建层缓存与 npm 下载缓存用同一个“缓存成功”标签带过。
| 情况 | 先看哪里 |
|---|---|
| 源码改动导致依赖重装 | COPY 顺序、上下文是否混入无关文件 |
| 安装步骤总是下载 | 实际 cache 路径、用户权限、builder 是否变化 |
| 本地有效,CI 首次无效 | builder 生命周期与外部缓存策略 |
| 缓存目录为空就构建失败 | 是否错误依赖缓存中的唯一文件 |
最后确认三件事:构建能在空缓存时成功,固定 builder 的重复构建能按输入复用,安装层重跑时缓存挂载使用正确路径。优化的结果应由自己的构建记录描述,不用本文说明图替代数据。
常见问题
cache mount 会把 npm 缓存带进最终镜像吗?挂载内容不作为该指令的普通镜像产物保存;安装在挂载之外的 node_modules 才随镜像层保留。
层缓存命中后还会执行 npm ci 吗?命中并复用该步骤时不会重新执行,这与执行安装时使用下载缓存是两回事。
清缓存是否是排障第一步?不是。先确认输入、路径和 builder,清理会影响其他构建并破坏观察条件。
参考:https://docs.docker.com/build/cache/optimize/;Dockerfile 字段:https://docs.docker.com/reference/dockerfile/;界面入口:https://docs.docker.com/desktop/use-desktop/builds/。
GitHub Copilot CLI 怎样在终端查看 PR
- 上一篇
- GitHub Copilot CLI 怎样在终端查看 PR
- 下一篇
- Docker Compose profiles 依赖服务分属不同 profile 时的启动配置
-
- 文章 · 软件教程 | 48分钟前 | 团队协作 · JetBrains IDE 项目级代码格式 Code Style Project scheme .idea/codeStyles
- JetBrains IDE 怎样配置项目级代码格式
- 359浏览 收藏
-
- 文章 · 软件教程 | 52分钟前 |
- Git rebase 冲突怎样保留两边文件片段
- 359浏览 收藏
-
- 文章 · 软件教程 | 56分钟前 |
- Git rerere 怎样复用重复冲突的解决结果
- 438浏览 收藏
-
- 文章 · 软件教程 | 1小时前 | docker · 容器编排 Docker Compose Profiles depends_on
- Docker Compose profiles 依赖服务分属不同 profile 时的启动配置
- 423浏览 收藏
-
- 文章 · 软件教程 | 1小时前 |
- GitHub Copilot CLI 怎样在终端查看 PR
- 176浏览 收藏
-
- 文章 · 软件教程 | 1小时前 |
- GitHub Actions 怎样缓存 Go 模块
- 470浏览 收藏
-
- 文章 · 软件教程 | 1小时前 |
- VS Code 调试配置怎样传递环境变量
- 474浏览 收藏
-
- 文章 · 软件教程 | 1小时前 | gitHub actions · 持续集成 · GitHub Actions workflow_dispatch inputs 手动运行工作流
- GitHub Actions 手动运行工作流怎样传入参数
- 216浏览 收藏
-
- 文章 · 软件教程 | 1小时前 | 开发工具 · vs code · VS Code extensions.json 多根工作区 扩展推荐
- VS Code 多根工作区怎样分别管理扩展推荐
- 228浏览 收藏
-
- 文章 · 软件教程 | 13小时前 |
- OBS怎样把麦克风与桌面声音录到不同音轨
- 174浏览 收藏
-
- 文章 · 软件教程 | 13小时前 | Audacity 标签轨 拆分音频 Multiple Files Export Audio
- Audacity怎样用标签轨拆分自录音频
- 314浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 467次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 530次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 548次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 497次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 317次使用
-
- VS Code 怎么给 Go 项目配置测试任务:tasks.json 运行与结果验收
- 2026-07-09 501浏览
-
- Windows 11 如何开启 HEIF 图片支持
- 2026-05-31 501浏览
-
- TikTok用户画像与付费订阅变现方法
- 2026-05-27 501浏览
-
- 学信网学历翻译件申请方法
- 2026-05-27 501浏览
-
- Windows 11 24H2 更新失败0x80070005解决方法
- 2026-05-26 501浏览

