脚本式Jenkinsfile流水线如何正确构建并运行Docker镜像
核心故障原因
你看到的BuildMachine1 does not seem to be running inside a container是Docker流水线插件输出的普通信息级日志,不是报错,和你内层代码不执行没有关系。
真正的问题是Groovy语法换行导致闭包绑定失效:
你把.inside单独拆成了一行,Groovy解析代码时会认为行尾就是表达式结束位置,会把.inside识别为无参数的单独方法调用,后面跟的花括号代码块会被当成孤立的闭包,根本没有作为参数传入inside()方法。最终效果就是插件只执行了启动容器的逻辑,没收到你要在容器内运行的echo、make指令,容器启动后直接走清理流程退出,你写的内层代码完全不会被执行。
另外你贴的日志里还存在镜像tag不一致的问题:构建成功的镜像tag是build-image:79,后续启动容器用的却是build-image:87,说明你多次重跑构建时没有清理旧镜像,或者代码里的tag取值逻辑存在偏差,链式调用时不会出现这个问题,改完语法后可以顺带检查。
修复方案
- 修正代码换行格式,不要把
.inside单独拆行,保证闭包直接作为参数传入inside()方法,不要让Groovy把方法调用和后续闭包拆成两个独立的语法单元。 - 如果你的自定义镜像设置了非空ENTRYPOINT,需要在调用inside时传入空entrypoint参数,避免插件用来保活容器的
cat命令被ENTRYPOINT拦截导致容器秒退。
修正后的可运行代码如下:
node('BuildMachine1') { withEnv(envList) { dir("/some/path") { // 注意.inside()直接跟在build方法返回结果后,闭包紧接在方法调用后不要断行 docker.build("build-image:${env.BUILD_ID}", "-f ${env.WORKSPACE}/build/Dockerfile .") .inside('--entrypoint ""') { echo "Echo from Docker" sh 'make' } } } }
补充说明
- 你之前对Docker流水线的理解存在偏差:脚本式流水线中
inside()方法会自动复用当前已经分配的构建节点(也就是你指定的BuildMachine1),不需要额外嵌套node块,也不会把容器当成独立的新构建节点调度,插件会自动在当前节点启动容器、挂载工作目录、把闭包里的步骤注入容器内执行,执行完成后自动销毁容器。 - 如果后续需要给容器加额外挂载、环境变量,直接把docker run对应的参数作为字符串传入
inside()方法即可,和你在命令行用docker run的参数写法完全一致。
内容的提问来源于stack exchange,提问作者J. Mueller
相关产品推荐
相关产品推荐

