GitLab CI stop-job执行失败(exit status 1)求助排查
问题定位与修复方案
1. 语法错误:多余的脚本行位置错误
你的.gitlab-ci.yml最后一行- echo 'Stopping job completed!'缩进错误,它被错误放在了only块的外部、job的顶级配置中,这会导致GitLab CI解析配置时直接报错,触发job失败。
2. 依赖缺失:lsof未安装
GitLab Runner使用的默认镜像(如Debian/Ubuntu slim版、Alpine)通常未预装lsof工具,执行lsof -i :80会直接报错返回非0退出码,导致脚本中断、job失败。
3. 健壮性不足:进程计数逻辑的潜在问题
如果lsof执行失败,process_count变量会为空,后续的[ "$process_count" -eq 0 ]会触发shell错误——无法将空字符串与数字0进行比较。
修复后的完整.gitlab-ci.yml配置
stages: # 定义job执行阶段及顺序 - stop stop-job: # 该job在stop阶段执行,优先级最高 stage: stop before_script: # 根据Runner镜像选择包管理器安装lsof,这里以Debian/Ubuntu为例;Alpine镜像请用apk add --no-cache lsof - apt-get update && apt-get install -y lsof script: - echo 'Stopping job ...' # 向监听3000端口的服务发送优雅停止指令,无进程则提示 - echo 'shutdown' | nc localhost 3000 || echo 'No process listening on port 3000' - | while true; do # 安全获取80端口监听进程数,处理lsof执行失败的情况 process_count=$(lsof -i :80 | grep LISTEN | wc -l || echo 0) # 确保变量为数字,避免比较错误 process_count=${process_count:-0} # 检查80端口是否已无监听进程 if [ "$process_count" -eq 0 ]; then echo "There is no application or process using port 80" break fi echo "Port 80 is currently in use. Retrying in 5 seconds..." sleep 5 done - echo "Stopping job completed!" only: - main
额外优化建议
- 添加超时机制:避免循环无限等待,比如设置最大重试12次(共60秒),超时则主动退出:
retry_count=0 max_retries=12 while [ $retry_count -lt $max_retries ]; do process_count=$(lsof -i :80 | grep LISTEN | wc -l || echo 0) process_count=${process_count:-0} if [ "$process_count" -eq 0 ]; then echo "There is no application or process using port 80" break fi echo "Port 80 is in use. Retrying ($((retry_count+1))/$max_retries)..." sleep 5 retry_count=$((retry_count+1)) done if [ $retry_count -eq $max_retries ]; then echo "Timeout waiting for port 80 to be released" exit 1 fi - 更可靠的优雅停止方式:如果你的应用生成PID文件,可直接通过PID发送
SIGTERM信号,比如kill $(cat /path/to/app.pid),比依赖端口检测更稳定。
内容的提问来源于stack exchange,提问作者Monero Jeanniton
相关产品推荐
相关产品推荐

