惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

P
Proofpoint News Feed
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Microsoft Security Blog
Microsoft Security Blog
云风的 BLOG
云风的 BLOG
MongoDB | Blog
MongoDB | Blog
Know Your Adversary
Know Your Adversary
K
Kaspersky official blog
人人都是产品经理
人人都是产品经理
IT之家
IT之家
Recorded Future
Recorded Future
Recent Announcements
Recent Announcements
D
DataBreaches.Net
C
CXSECURITY Database RSS Feed - CXSecurity.com
U
Unit 42
博客园 - 【当耐特】
I
Intezer
Cisco Talos Blog
Cisco Talos Blog
Spread Privacy
Spread Privacy
L
LINUX DO - 热门话题
H
Help Net Security
L
LangChain Blog
T
The Exploit Database - CXSecurity.com
P
Palo Alto Networks Blog
Scott Helme
Scott Helme
The GitHub Blog
The GitHub Blog
博客园_首页
P
Proofpoint News Feed
大猫的无限游戏
大猫的无限游戏
S
Secure Thoughts
The Register - Security
The Register - Security
Engineering at Meta
Engineering at Meta
T
Threatpost
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Blog — PlanetScale
Blog — PlanetScale
C
Cybersecurity and Infrastructure Security Agency CISA
T
Troy Hunt's Blog
罗磊的独立博客
腾讯CDC
Simon Willison's Weblog
Simon Willison's Weblog
Security Latest
Security Latest
Last Week in AI
Last Week in AI
P
Privacy & Cybersecurity Law Blog
Latest news
Latest news
The Cloudflare Blog
Jina AI
Jina AI
小众软件
小众软件
Cloudbric
Cloudbric
TaoSecurity Blog
TaoSecurity Blog
F
Full Disclosure
V
V2EX

二丫讲梵

学习周刊-总第258期-2026年第15周 学习周刊-总第257期-2026年第14周 学习周刊-总第256期-2026年第13周 学习周刊-总第255期-2026年第12周 学习周刊-总第254期-2026年第11周 学习周刊-总第253期-2026年第10周 临时插播一条羊毛,免费领取450元大模型API代金券 学习周刊-总第252期-2026年第09周 学习周刊-总第251期-2026年第08周 学习周刊-总第250期-2026年第07周 学习周刊-总第249期-2026年第06周 诚邀评论,聊聊你所知欲知的我 学习周刊-总第248期-2026年第05周 我的QQ动态之2015年 我的QQ动态之2014年 我的QQ动态之2013年 我的QQ动态之2012年 我的QQ动态-2010-2011年 我的QQ动态-创栏小叙 学习周刊-总第247期-2026年第04周 Nexus社区版权益阉割--一文告诉你有哪些版本可以选择 学习周刊-总第246期-2026年第03周 学习周刊-总第245期-2026年第02周 学习周刊-总第244期-2026年第01周 学习周刊-总第243期-2025年第52周 学习周刊-总第242期-2025年第51周 开源项目ZenOps:带你领略禅意运维 学习周刊-总第241期-2025年第50周 用京东金融,享负债人生 学习周刊-总第240期-2025年第49周 学习周刊-总第239期-2025年第48周 整理我在静态服务透明代理上的极致求索之路,最后一个你绝想不到 学习周刊-总第238期-2025年第47周 我们输了,但收获颇多 太多了,太多了 学习周刊-总第237期-2025年第46周 学习周刊-总第236期-2025年第45周 学习周刊-总第235期-2025年第44周 二五年国庆二三事 学习周刊-总第234期-2025年第43周 学习周刊-总第233期-2025年第42周 学习周刊-总第232期-2025年第41周 学习周刊-总第231期-2025年第40周 学习周刊-总第230期-2025年第39周 西湖毅行 2025年开源世界逸闻三则 学习周刊-总第229期-2025年第38周 手抄《与妻书》 学习周刊-总第228期-2025年第37周 父亲善行录 学习周刊-总第227期-2025年第36周 带你认识我之看看我的高中同学录(其二) 学习周刊-总第226期-2025年第35周 带你认识我之看看我的高中同学录(其一) 认识神级MCP工具系列--用anyquery和数据库交互 学习周刊-总第225期-2025年第34周 学习周刊-总第224期-2025年第33周 学习周刊-总第223期-2025年第32周 学习周刊-总第222期-2025年第31周 学习周刊-总第221期-2025年第30周 CNB云原生开发环境届的瑞士军刀,详解qifei项目 vuepress-vdoing主题配置自建不蒜子统计 学习周刊-总第220期-2025年第29周 写在博客发表文章1000篇的节点 从claude cli的体验聊聊最大的敌人是我们自己的成见 学习周刊-总第219期-2025年第28周 学习周刊-总第218期-2025年第27周 学习周刊-总第217期-2025年第26周 理论正确,事实错误 学习周刊-总第216期-2025年第25周 学习周刊-总第215期-2025年第24周 学习周刊-总第214期-2025年第23周 学习周刊-总第213期-2025年第22周 学习周刊-总第212期-2025年第21周 从赵心童世锦赛夺冠聊聊我的斯诺克情缘 学习周刊-总第211期-2025年第20周 记录二五年五一之短暂回归家庭 学习周刊-总第210期-2025年第19周 学习周刊-总第209期-2025年第18周 学习周刊-总第208期-2025年第17周 Go开发实践之Gin框架将前端的dist目录embed到二进制 学习周刊-总第207期-2025年第16周 近期关于cobra库的一些实践心得总结 学习周刊-总第206期-2025年第15周 我的嗜好--嗑瓜子 记大宝参加幼儿园组织的清明烈士陵园扫墓活动 学习周刊-总第205期-2025年第14周 学习周刊-总第204期-2025年第13周 前端开发小笔记--在数组中给字段添加值与删除字段的操作 学习周刊-总第203期-2025年第12周 人生实苦,何以自渡 学习周刊-总第202期-2025年第11周 近期发现的一些优秀的工具提名(一) 学习周刊-总第201期-2025年第10周 学习周刊-总第200期-2025年第09周 记一次女友喝醉使我忍术破功 爱情风波--一次分手又复合的经历 学习周刊-总第199期-2025年第08周 整理我的信息源 学习周刊-总第198期-2025年第07周
CNB开发与构建基于docker-cache缓存复用的配置实践心得
二丫讲梵 · 2025-09-15 · via 二丫讲梵

# 前言

在参加 CNB 官方组织的 玩转云原生开发环境 问答攻守擂台赛 (opens new window)时,我遇到了有两位同学问到如何在 CNB 中利用构建缓存加速的问题,于是深入了解研究了下,今天来把一些心得成果做一下记录。

之前之所以没有折腾这个课题,是因为 CNB 提供的构建环境,已经针对大部分开发语言的仓库做了加速,因此基本不会出现依赖安装很慢或者安装不下去的情况,就算每次新安装也不过一分钟内就完事儿,符合正常的心理预期,便没有过多深入。

# 基于 Volumes 的缓存

官方文档:volumes (opens new window) 这个内容官方文档已经介绍的很详细了,我就不多赘述了。

个人使用的一个案例见:test1.yml (opens new window)

# 基于 docker cache 的缓存

这也是本文要详细介绍的一种缓存机制,比较通用,不受构建机分配的影响。

官方文档:docker-cache (opens new window)

可通过阅读官方文档,了解此功能运行原理和机制,接下来我将直接通过实际应用案例,来介绍一下个人理解的最佳实践。

我这里以前端 node 项目举例子,我们在项目根目录创建构建 docker-cache 缓存的 Dockerfile:

$ cat .cache.dockerfile

FROM node:20.19.5-alpine3.22 as Builder

WORKDIR /space

COPY . .

RUN npm i -g pnpm && pnpm install --registry=http://registry.npmmirror.com

ENV NODE_PATH=/space/node_modules

1
2
3
4
5
6
7
8
9
10
11

然后在 .cnb.yml 中添加如下构建配置:

$:
  push:
    - runner:
        cpus: 16
      services:
        - docker
        - git-clone-yyds
      stages:
        - name: 构建缓存镜像
          type: docker:cache
          options:
            dockerfile: cache.dockerfile
            by:
              - package.json
              - pnpm-lock.yaml
            versionBy:
              - pnpm-lock.yaml
          exports:
            name: DOCKER_CACHE_IMAGE_NAME
        - name: 直接使用缓存镜像环境安装依赖并编译
          image: $DOCKER_CACHE_IMAGE_NAME
          script: |
            ln -snf $NODE_PATH node_modules
            ls -ahl && du -sh node_modules
            time pnpm install
            time npm run build

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

这里有几个比较重要的实践心得,统一汇总如下:

  • 构建缓存使用的基础镜像首先要能满足依赖安装的基础要求,在此前提之下,基础镜像越小越好,因此可以选择官方镜像,且 tag 中带 alpine 的镜像。这样除了可以保障下边依赖安装和构建的流程走完,还能极大程度上在首次拉取缓存镜像时尽可能消耗更短的时间。
  • 使用构建缓存的最佳实践是:直接在缓存镜像中构建,通过 ln 命令把依赖软链到工作区,为了确保依赖完全对齐,还可以再执行一次 install,这个时候基本上耗时在一两秒。官方文档介绍的方案是把 node_modules 目录拷贝到工作区,耗时会比这个要高。

再补充说明一下构建缓存镜像的机制:

  • 缓存镜像是否进行构建,判断依据的逻辑表达式为:sha1(Dockerfile + versionBy + buildArgs + target + arch),在进行构建时,会先获取到这个值,然后通过 docker image inspect 命令测试构建主机是否存在该镜像,若有,则直接使用,如果没有,则通过 docker pull 命令测试远程制品库是否存在该镜像,若有,则 pull 之后使用,如果没有,则通过 docker build 开始构建缓存镜像。通过下图实际构建日志可见:
  • 因为 DockerfilebuildArgstargetarch 这几个参数通常是不变的,因此,后续的构建过程中,判断是否重新构建缓存镜像的关键点,就在于 versionBy 指定的文件内容是否变化了。因此这个文件通常建议指定为对应语言的依赖版本管理文件,如 package.jsongo.mod 等。

如此配置之后,只有第一次构建,以及后续依赖版本有变化的时候才会触发缓存镜像的构建,否则就会直接复用之前构建过程中已经制作好的缓存镜像,从而达到加速构建的目的。

# 云原生开发复用构建缓存

基于如上云原生构建复用依赖缓存的思路,接下来再介绍下云原生开发场景中,如何复用构建缓存。

有不少同学,会在配置云原生开发的配置中,增加依赖安装的命令,以达到打开开发环境,直接可以使用的目的,那么如何在云开发环境中复用构建缓存呢?

可使用如下配置:

$:
  vscode:
    - docker:
        image: docker.cnb.cool/znb/images/debian:new
      runner:
        cpus: 8
      services:
        - vscode
        - docker
      stages:
        - name: 构建缓存镜像
          type: docker:cache
          options:
            dockerfile: cache.dockerfile
            by:
              - package.json
              - pnpm-lock.yaml
            versionBy:
              - pnpm-lock.yaml
          exports:
            name: DOCKER_CACHE_IMAGE_NAME
        - name: 复用构建缓存
          image: $DOCKER_CACHE_IMAGE_NAME
          script: |
            time pnpm install
        - name: vscode go
          type: vscode:go
        - name: test
          script: |
            ls -al

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

要素说明:

  • 在这个场景中,就不适合使用 ln 来复用依赖目录了,否则就会导致该步骤完成之后,缓存镜像销毁,软链的源目录自然也就没有了,从而导致云开发环境中的 node_modules 变成一个无效的软链。直接执行 pnpm install 会复用缓存镜像中的 ~/.pnpm 目录下的缓存,从而同样达到加速的目的。
  • 如上配置中增加了一个 vscode:go 的指令,详细说明见官方文档 (opens new window),简单理解该指令在 stages 中就是一个分割线,vscode:go 以上的内容,会在云原生开发环境创建之前执行,vscode:go 以下的内容,会在云原生开发环境创建完成后执行。增加这个指令,是为了保障某些依赖在环境创建之前安装完毕。

# 最后

docker-cache 的缓存利用机制是通用的,这里用 node 项目进行举例,其他语言的项目同理亦可复用。