如何通过Jenkins脚本在Docker容器内部执行命令
问题根因
你遇到的问题来自两个书写错误和一个参数使用误区:
- 原脚本中
docker run的参数没有正确续行:镜像名i-st-pd-docker-vxxxxxx所在行的末尾没有加\续行符,导致docker run命令执行到镜像名就已经结束,后面的bash | hostname完全是在宿主机上执行的,根本没有进入容器运行。 - 管道符
|的解析层级错误:就算你加了续行,bash | hostname的写法也是把容器内bash的输出通过管道传给宿主机的hostname命令,最终输出的自然是宿主机的主机名,和容器内环境无关。 -t参数使用场景错误:Jenkins的sh步骤运行在无TTY的非交互式环境中,docker run的-t参数作用是分配伪终端,在无TTY环境下使用就会抛出the input device is not a TTY报错。CI流水线场景下不需要加这个参数,只保留-i(保持标准输入打开)即可满足非交互执行需求。
可直接使用的修正方案
把所有需要在容器内执行的命令,通过bash -c "命令列表"的形式作为docker run的最终传入参数,同时补全所有续行符,不要把要在容器内跑的逻辑写到docker run参数外面。
修正后的流水线脚本示例:
pipeline { agent { label 'machine' } stages { stage('GC Open Build') { steps { sh ''' docker run -i --rm \ -u $(id -u):$(id -g) \ -e USER_NAME=$(id -un) \ -e GROUP_NAME=$(id -gn) \ -e HOME \ -v $HOME:$HOME \ -v /PROJ:/PROJ:shared \ -v /srv:/srv \ -w $PWD \ i-st-pd-docker-vxxxxxx \ bash -c " # 以下所有命令均在容器内部执行 hostname # 可按需求追加其他命令,例如: # pwd # 你的项目构建、编译相关命令 " ''' } } } }
补充说明
- 如果后续需要执行的容器内命令较多,可以直接把构建逻辑写到独立的shell脚本里,通过volume挂载到容器中再执行,避免在
bash -c里写过多引号嵌套的内容,降低出错概率。 - 只有当你需要手动登录容器做交互调试的时候,才需要加
-t参数,流水线自动执行场景永远不要加这个参数。
内容的提问来源于stack exchange,提问作者arama mihai
相关产品推荐
相关产品推荐

