解决jinkins的CI、CD使用非root执行sudo命令时无密码权限导致报错的问题

一、核心错误原因(日志关键片段)

在「🚀 部署到目标目录」阶段,执行 sudo chmod 755 /home/aicloud/docker/nginx/html/dist/ 命令时,Jenkins 代理节点(运行任务的机器)返回了明确的错误:

bash

vbnet 复制代码
sudo: a terminal is required to read the password; either use the -S option to read from standard input or configure an askpass helper
sudo: a password is required
  • 含义:sudo 命令需要交互式输入用户密码才能执行,但 Jenkins 任务是「无终端(non-interactive)」的后台运行模式,无法弹出终端让用户输入密码,因此命令执行失败,直接导致该阶段报错。
  • 连锁影响:由于「部署到目标目录」阶段失败,后续的「🔧 启动服务」阶段被自动跳过(日志提示 skipped due to earlier failure(s)),最终整个流水线以 ERROR: script returned exit code 1 终止,标记为 FAILURE

具体失败原因:Jenkins 执行 sudo 命令时无密码权限,无法完成目标目录的权限修改操作,导致部署流程中断。

CI:

bash 复制代码
echo "开始构建前端项目..."

cd ruoyi-ui
echo "进入ruoyi-ui目录"

npm install
echo "依赖安装完成"

npm run build:prod
echo "生产环境构建完成"

tar -czf dist.tar.gz dist/
echo "将当前目录下的 dist 文件夹及其所有内容,打包并通过 gzip 压缩,已生成名为 dist.tar.gz 的压缩包"

echo "前端项目构建全部完成"

CD:(关键举措:chmod 755 ${env.FRONTEND_DIR})

python 复制代码
pipeline {
agent {
    label 'sit'
}

environment {
    // 使用绝对路径,基于远程节点的工作目录 /home/aicloud/
    FRONTEND_DIR = '/home/aicloud/docker/nginx/html/dist/'
}

stages {
    stage('📥 从 CI 流水线复制制品') {
        steps {
            script {
                echo "开始从 CI 复制最新成功构建的制品..."
                
                // 显示当前工作目录
                sh 'echo "当前工作目录: $(pwd)"'

                // 创建本地目录
                sh '''
                    mkdir -p artifacts/frontend
                '''
                // 复制制品
                copyArtifacts(
                    projectName: 'CI',
                    filter: 'ruoyi-ui/dist.tar.gz',
                    target: 'artifacts/frontend/',
                    selector: lastSuccessful(),
                    flatten: true
                )
  

    


         

           

         

          


                // 检查复制结果
                sh '''
                    echo "复制结果检查:"
                    echo "当前目录下的文件:"
                    pwd
                    ls -la
                    echo "artifacts 目录内容:"
                    ls -la artifacts/
                    echo "前端制品:"
                    ls -la artifacts/frontend/
                '''
            }
        }
    }

    stage('🚀 部署到目标目录') {
        steps {
            script {
                echo "开始部署服务到目标目录..."
                
                // 显示目标目录信息
                sh """
                    echo "目标部署目录:"
                    echo "前端: ${env.FRONTEND_DIR}"
          
                """

                // 创建目标目录(确保有权限)
                sh """
                    # 创建前端目录
                    mkdir -p ${env.FRONTEND_DIR}
                    
 
                    
                    # 设置目录权限(如果需要)
                    chmod 755 ${env.FRONTEND_DIR}
  
                """

                // 部署前端:清空目录并解压dist包
                sh """
                    echo "正在部署前端..."
                    # 清空前端目录(删除所有文件和子目录)
                    echo "清空前端目录: ${env.FRONTEND_DIR}"
                    rm -rf ${env.FRONTEND_DIR}* 2>/dev/null || true
                    rm -rf ${env.FRONTEND_DIR}.* 2>/dev/null || true
                    
                    # 检查目录是否已清空
                    echo "清空后目录内容:"
                    ls -la ${env.FRONTEND_DIR} || echo "目录为空或不存在"
                    
                    # 解压前端dist包
                    echo "解压前端dist包到: ${env.FRONTEND_DIR}"
                    tar -xzf artifacts/frontend/dist.tar.gz -C ${env.FRONTEND_DIR} --strip-components=1
                    
                    echo "前端部署完成,目录内容:"
                    ls -la ${env.FRONTEND_DIR} || echo "前端目录不存在"
                """

       

                // 验证文件是否复制成功
                sh """
                    echo "部署后验证:"
                    echo "前端目录文件:"
                    ls -la ${env.FRONTEND_DIR} || echo "前端目录不存在"
             
                """

                echo "✅ 文件已部署到目标目录"
            }
        }
    }

    stage('🔧 启动服务') {
        steps {
            script {
                echo "正在启动服务..."

                // 这里根据你的实际启动脚本进行调整
                sh """
                    echo "✅ 开始重启服务..."
                    echo "✅ 文件位置验证:"
                    echo "前端目录: ${env.FRONTEND_DIR}"
   
                    
                    # 检查文件是否存在
                    if [ -d "${env.FRONTEND_DIR}" ] && [ "\$(ls -A ${env.FRONTEND_DIR})" ]; then
                        echo "✅ 前端文件存在且不为空"
                    else
                        echo "❌ 前端文件不存在或为空"
                    fi
  
                    
  
            
                    
     
               

                    echo "✅ 开始重启服务..."
                    cd /home/aicloud/docker/
                    
                    # 先停止和清理容器
                    docker stop ruoyi-view ruoyi-nginx  2>/dev/null || true
                    
                    docker rm ruoyi-view ruoyi-nginx 2>/dev/null || true
                    
                  
                    
                    # 执行部署脚本
                    echo "执行基础部署..."
                    ./deploy.sh base
                    
                    echo "执行模块部署..."
                    ./deploy.sh modules_all
                    
                    echo "✅ 所有服务部署完成!"
                """
                
                // 这里可以添加实际的服务启动命令,例如:
                // sh "systemctl restart your-service-name"

            }
        }
    }
}

post {
    success {
        echo "✅ 部署成功完成!"
    }
    failure {
        echo "❌ 部署失败,请检查日志!"
    }
    always {
        // 清理工作空间
        cleanWs()
    }
}
}
相关推荐
携欢3 小时前
POrtSwigger靶场之CSRF where token validation depends on token being present通关秘籍
前端·csrf
weixin_446260853 小时前
MudBlazor:轻松构建美观的Web应用程序!
前端
谜亚星3 小时前
GSAP学习(五)
前端·动效
code_Bo3 小时前
基于vxe-table进行二次封装
前端·javascript·vue.js
小时前端3 小时前
现代Web认证体系深度解析:从JWT原理到SSO架构设计
前端·面试
前端一课4 小时前
公开分享一个AI番茄短故事模块技术方案(含代码)
前端
晴殇i4 小时前
为什么现代 JavaScript 代码规范开始建议禁止使用 else ?
前端·javascript·前端框架
源力祁老师4 小时前
OWL与VUE3 的高级组件通信全解析
前端·javascript·vue.js
花开月正圆4 小时前
遇见docker-compose
前端