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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 05:23:16