Jenkins流水线执行docker exec -t命令长时间卡住无法完成阶段如何解决
问题根因
- 伪终端参数冲突:Makefile中
exec命令的docker exec -t merchant-dashboard bash使用了-t参数分配伪终端,Jenkins执行Shell步骤属于非交互式运行环境,不存在可用终端,命令会持续等待终端响应导致卡住。 - 驻留进程无退出逻辑:
docker exec后直接启动了bash交互进程,本地运行时可手动输入命令执行后通过exit退出进程,而Jenkins非交互环境没有后续输入,bash进程会持续驻留,导致步骤永远不会完成。 - 逻辑错误:你当前流水线的写法下,
npm run build和npm run test:e2e实际是运行在Jenkins Agent节点本地,而非预期的容器内部,就算不卡住也无法得到正确的构建结果。
解决方案
方案1:调整流水线执行逻辑(推荐)
直接抛弃原有的make exec调用,利用Docker命令直接在容器内执行对应任务,同时复用Makefile中已有的测试命令:
修改Jenkinsfile的Build和Test阶段如下:
stage('Build') { steps { echo 'Destroy Old Build' sh 'make destroy' echo 'Building' // 仅后台启动容器,不进入交互终端 sh 'make upbuild_d' // 直接在容器内执行构建命令,不需要伪终端参数 sh 'docker exec merchant-dashboard npm run build' } } stage('Test') { steps { echo 'Running Tests' // 直接调用Makefile中已封装的e2e测试命令,自动在容器内执行 sh 'make test-e2e' } }
方案2:修改Makefile适配CI环境
如果你希望保留Makefile的统一调用逻辑,可以新增专门用于CI环境的非交互执行命令:
在Makefile中新增以下配置:
exec-ci: docker-compose -f docker-compose.local.yml up -d --build && docker exec merchant-dashboard $(CMD)
修改Jenkinsfile对应阶段:
stage('Build') { steps { echo 'Destroy Old Build' sh 'make destroy' echo 'Building' sh 'make exec-ci CMD="npm run build"' } }
两种方案都可以解决卡住问题,同时保证构建和测试命令运行在目标容器内部。
内容的提问来源于stack exchange,提问作者Mona101ma
相关产品推荐
相关产品推荐

