当前位置: 首页 > news >正文

记一次 dockerfile 的循环依赖错误

文章目录

    • 1. 写在最前面
      • 1.1 具体循环依赖的例子
    • 2. 报错的位置
      • 2.1 代码快速分析
      • 2.2 代码总结
      • 2.3 关于 parser 的记录
    • 3. 碎碎念

1. 写在最前面

笔者在使用 dockerfile 多阶段构建的功能时,写出了一个「circular dependency detected on stage: xx」的错误。

解决方式:解耦互相依赖的构建阶段即可,构建 A <=> 构建 B 两个阶段是互相依赖的,改为构建 A => 构建 B

注:「多阶段构建」是 Docker 提供的一种功能,运行用户在一个 Dockerfile 中定义多个构建阶段,从而优化构镜像的大小和构建过程的效率。通过这种方式,开发者可以在不同的阶段使用不同的基础镜像和工具,最终只将所需要的文件和依赖项复制到最终的镜像中。

但是,作为一个有求知精神的软件开发工程师,笔者去翻看了一下源码的位置。(ps: 其实就是自己感兴趣 BuildKit 的源码想要学习一下,而带着问题学习的速度更快)

1.1 具体循环依赖的例子

FROM busybox AS stage0
COPY --from=stage0 f1 /sub/ 
  • FROM busybox AS stage0: 这行代码定义了一个名为 stage0 的构建阶段,并使用 busybox 作为基础镜像。

  • COPY --from=stage0 f1 /sub/: 这行代码尝试从名为 stage0 的构建阶段复制文件 f1/sub/ 目录。

在这个情况下,在同一个构建阶段中同时定义了一个新的阶段并尝试从该阶段复制文件。这会导致 Docker 无法解析这个依赖关系,因为 stage0 还没有完成构建就被引用了。

2. 报错的位置

源码仓库:GitHub - moby/buildkit: concurrent, cache-efficient, and Dockerfile-agnostic builder toolkit

具体位置:buildkit/frontend/dockerfile/dockerfile2llb/convert.go at master · moby/buildkit · GitHub

在这里插入图片描述

2.1 代码快速分析

得益于 Github 支持了 Codespaces 让笔者可以无需代码下载到本地,可以直接基于 Codespaces 对 「convert_test.go」的具体 case 直接做在线 debug ,逐行分析。

注:GitHub Codespaces 是一个基于云的开发环境,允许开发者在浏览器中创建和使用完整的开发环境。它旨在简化开发流程,特别是对于团队协作和快速启动项目。以下是 GitHub Codespaces 的一些关键特性和功能:

代码 debug 效果:

在这里插入图片描述

注:感慨一下 Codespaces 真的香!

2.2 代码总结

核心的循环依赖检测逻辑代码如下:

func validateCircularDependency(states []*dispatchState) error {var visit func(*dispatchState, []instructions.Command) []instructions.Commandif states == nil {return nil}visited := make(map[*dispatchState]struct{})path := make(map[*dispatchState]struct{})visit = func(state *dispatchState, current []instructions.Command) []instructions.Command {_, ok := visited[state]if ok {return nil}visited[state] = struct{}{}path[state] = struct{}{}for dep, c := range state.deps {next := append(current, c)if _, ok := path[dep]; ok {return next}if c := visit(dep, next); c != nil {return c}}delete(path, state)return nil}for _, state := range states {if cmds := visit(state, nil); cmds != nil {err := errors.Errorf("circular dependency detected on stage: %s", state.stageName)for _, c := range cmds {err = parser.WithLocation(err, c.Location())}return err}}return nil
}

核心分析:它使用深度优先搜索(DFS)的方式来检测循环依赖,并在发现循环时返回一个错误。

注:看来不是算法没有用,是业务逻辑的代码中使用 DFS 这种算法的场景比较少,还是得多看源码

2.3 关于 parser 的记录

对于 dockerfile 的 parser 也有点兴趣,后面要继续抽个时间深入分析一下。笔者当前负责的模块重构成一个通用的 parser 的话,代码的复用率会更高一点。希望后面有时间可以优化改进一波

3. 碎碎念

抓住 2024 的尾巴,努力学习感兴趣的知识。希望 2025 平安喜乐,万事胜意!

  • 最好的选择是,做自己的太阳

  • 幸福的秘诀是,拥有苹果时,只在意苹果,不去管橘子,更不要想橙子的事情。

  • 终于明白朝花夕拾什么意思了,你一生追求的东西其实一开始就在,只是你后知后觉而已,人无法同时拥有青春和对于青春的感受,有些东西要靠消失才能证明它的珍贵。

http://www.lryc.cn/news/512884.html

相关文章:

  • Trimble天宝X9三维扫描仪为建筑外墙检测提供了全新的解决方案【沪敖3D】
  • 【MySQL】深度学习数据库开发技术:使用CC++语言访问数据库
  • LabVIEW化工实验室设备故障实时监测
  • 单例模式懒汉式、饿汉式(线程安全)
  • Cursor登录按钮点击没反应
  • 论文实现:Reactive Nonholonomic Trajectory Generation via Parametric Optimal Control
  • 基于单片机中药存放环境监测系统的实现
  • 九垠赢+商业管理系统 Common.ashx 文件上传致RCE漏洞复现
  • 速盾:服务器CDN加速解析的好处有哪些呢?
  • C++ 设计模式:备忘录模式(Memento Pattern)
  • Android 系统 Activity 系统层深度定制的方法、常见问题以及解决办法
  • PDF怎么压缩得又小又清晰?5种PDF压缩方法
  • YK人工智能(三)——万字长文学会torch深度学习
  • 关于CISP报名费用详情
  • vim 按下esc后取消高亮
  • SwiftUI:多语言实现富文本插值
  • 操作系统基础
  • 函数调用流程可用工具
  • UniApp 页面布局基础
  • 2D图像测量到3D点云之物体三维尺寸测量!!!!
  • [TOTP]android kotlin实现 totp身份验证器 类似Google身份验证器
  • 2025决战智驾:从中阶卷到L3,车企需要抓好一个数据闭环
  • 电子电气架构 --- 汽车电子电器设计概述
  • SpringAI从入门到熟练
  • [算法] [leetcode-20] 有效的括号
  • R语言入门笔记:第一节,快速了解R语言——文件与基础操作
  • 【亚马逊云】基于Amazon EC2实例部署 NextCloud 云网盘并使用 Docker-compose 搭建 ONLYOFFICE 企业在线办公应用软件
  • java Redisson 实现限流每秒/分钟/小时限制N个
  • 【漫话机器学习系列】029.累积分布函数(Cumulative Distribution Function)
  • 设计模式之访问者模式:一楼千面 各有玄机