You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jenkins流水线使用Hadolint v2.8.0执行Dockerfile lint时出现OCI运行时错误,切换v1.18.0版本正常

Jenkins流水线使用Hadolint v2.8.0执行Dockerfile lint时出现OCI运行时错误,切换v1.18.0版本正常

看起来你遇到的问题是Hadolint镜像版本更新后基础镜像变更导致的——v2.x版本的hadolint/hadolint镜像改用了scratch基础镜像(完全最小化,没有任何shell环境),而v1.18.0这类旧版本是基于带shell的Linux发行版镜像构建的。

错误原因分析

你的流水线脚本里用了hadolint Dockerfile > hadolint-results.txt,这里的>重定向是shell的核心功能,但scratch镜像里没有bash/sh这类shell程序,也没有cat、echo这类基础系统命令(错误日志里提到的exec: "cat"找不到,其实是Jenkins在尝试启动容器时,默认依赖shell执行操作导致的失败)。

解决方案

这里有几个可行的解决办法,你可以根据需求选择:

  • 方案一:使用带shell的Hadolint镜像变体
    Hadolint官方提供了基于Debian的镜像变体(后缀为-debian),这个版本包含完整的shell环境,可以完美支持重定向这类shell操作。只需要修改你的流水线镜像配置即可:

    stage("Lint") {
        agent {
            docker {
                image "docker.io/hadolint/hadolint:v2.8.0-debian"
                reuseNode true
            }
        }
        steps {
            script {
                def result = sh label: "Lint Dockerfile",
                    script: """\
                    hadolint Dockerfile > hadolint-results.txt
                    """,
                    returnStatus: true
                if (result > 0) {
                    unstable(message: "Linting issues found")
                }
            }
        }
    }
    
  • 方案二:避免shell重定向,用Jenkins步骤处理输出
    如果不想更换镜像,可以通过Jenkins的sh步骤捕获命令输出,再用writeFile写入文件,完全绕开shell的重定向依赖:

    stage("Lint") {
        agent {
            docker {
                image "docker.io/hadolint/hadolint:v2.8.0"
                reuseNode true
            }
        }
        steps {
            script {
                // 捕获lint输出并写入文件
                def lintOutput = sh label: "Lint Dockerfile",
                    script: "hadolint Dockerfile",
                    returnStdout: true
                writeFile file: "hadolint-results.txt", text: lintOutput
                
                // 检查lint结果状态
                def result = sh label: "Check lint status",
                    script: "hadolint Dockerfile",
                    returnStatus: true
                if (result > 0) {
                    unstable(message: "Linting issues found")
                }
            }
        }
    }
    
  • 方案三:覆盖容器的Entrypoint
    你可以在docker agent配置里直接覆盖镜像的entrypoint为hadolint,这样可以直接执行命令,但这种方式不支持复杂的shell操作,适合只需要执行lint命令、不需要保存输出的场景:

    stage("Lint") {
        agent {
            docker {
                image "docker.io/hadolint/hadolint:v2.8.0"
                reuseNode true
                entrypoint ["hadolint"]
            }
        }
        steps {
            script {
                def result = sh label: "Lint Dockerfile",
                    script: "Dockerfile",
                    returnStatus: true
                if (result > 0) {
                    unstable(message: "Linting issues found")
                }
            }
        }
    }
    

推荐方案

个人最推荐方案一,因为它几乎不需要修改你的原有脚本逻辑,同时能完整使用新版本Hadolint的所有功能,还保留了shell环境带来的灵活性。

备注:内容来源于stack exchange,提问作者ahmed mohamed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.20 13:00:30