
问题现象
私有镜像每次构建都从零开始,Docker log 只报 warning 但不报错。
配了 cache-from: type=local,明明什么都没改,缓存命中率却一直是 0%。明明跟着官方文档配的,怎么就不生效?
根因分析
问题出在 type=local 和 type=registry 的本质区别上。
type=local 把缓存存在 runner 本地磁盘,路径通常在 /tmp/buildx-cache/ 或 /runner/_work/_tool/。但 GitHub Actions 的 runner 是用完即回收的,下一次 workflow 跑起来,runner 早就换了一台机器。本地缓存?根本没机会用到。
type=registry 把缓存作为镜像层直接打包进 registry(GHCR、阿里云、腾讯云等),下次任何 runner 都能从 registry 拉取,缓存真正跨 job 生效。
实战案例:同一个项目,从 type=local 换成 type=registry 后,缓存命中率从 0% 拉到 70%+,构建时间从 11 分钟降到 3 分钟。
type=local vs type=registry 核心区别
| type=local | type=registry | |
|---|---|---|
| 存储位置 | runner 本地磁盘 | 镜像 registry |
| 跨 runner 生效 | ❌ 换机器即失效 | ✅ 任意 runner 通用 |
| 配置复杂度 | 简单 | 稍复杂(需 push 权限) |
| 缓存持久性 | runner 回收即丢失 | registry 存活期间永久有效 |
实战配置:type=registry 正确姿势 |
||
| ||
| uses: docker/build-push-action@v6 | ||
| with: | ||
| context: . | ||
| push: true | ||
| tags: ghcr.io/${{ github.repository }}/app:latest | ||
| cache-from: type=registry,ref=ghcr.io/${{ github.repository }}/app:buildcache | ||
| cache-to: type=registry,ref=ghcr.io/${{ github.repository }}/app:buildcache,mode=max | ||
关键:cache-to 和 cache-from 的 ref 必须相同,cache 层才会在下次 build 时被正确拉取。 |
||
| 两种模式也可以同时启用,local 加速本地,registry 保证跨 runner 持久化: | ||
| ||
| cache-to: type=registry,mode=max # 持久化 | ||
注意事项 |
||
用 type=local 时,如果 workflow 里前面 job 没执行完就跑当前 job,缓存还没生成,cache-from type=local 会静默失败(直接跳过,不用等超时)。 |
||
用 type=registry 时,registry 需要对这个仓库有 push 权限(公开仓库通常没问题),而且每次 cache-to 会额外 push 一些镜像层,增加镜像体积和 push 时间。 |
||
如果遇到 registry push 失败(权限或网络问题),cache-to 会报错中断构建,可以加 flare 调试: |
||
| ||
验证命令 |
||
看构建日志里有没有 CACHED 字样,或者直接对比阶段耗时: |
||
| ||
| # 对比构建总时间: | ||
| gh run view --log | grep "CACHED" |
现在你可以做什么
1. 把 docker/setup-buildx-action 之后的 cache-from: type=local 改成 type=registry
2. 加一条 cache-to: type=registry,ref=你的镜像:buildcache,mode=max
3. 确认 workflow 有 push 到对应 registry 的权限(通常 GITHUB_TOKEN 自动有 GHCR 权限)
4. 如果构建的是公开镜像,首次会慢一些(cache 层也要 push),之后就会快起来
© 版权声明
本站部分内容为网络收集,若侵犯到您的权益,请提供相关证明联系,即删。
更多交流点击入群
更多交流点击入群
THE END






