通用插件配置

在这里插入图片描述

在这里插入图片描述

SSH
在这里插入图片描述

构建:

  • 页面操作
  • pipeline 脚本操作

方式一: 页面操作

使用Jenkins自动部署一个vue项目
首先在dashboard > 新建项目Item。

可以按照自己的需求创建任务,我这里选的第一个 自己风格。

请添加图片描述
在这里插入图片描述

1、General一般设置

根据自己需求设置,这里我只设置了描述。
在这里插入图片描述

2、源码管理

1)Repository URL:这里设置Git代码仓库的地址

2)Credentials:这里设置Git认证凭据。点击添加一个凭据,可以选择账号密码,或者API Token,根据自己的需求选择。

3)Branches to build:这里设置Git源码的分支3、构建触发器

4)源码库浏览器:选自动即可
在这里插入图片描述

3、构建触发器 (不推荐使用,生产环境不可控重启时间)

可以选择(Push Events)当推送事件触发时,会自动进行构建。

这里注意需要去git上创建 webhook指向Jenkins这个地址,具体创建方法自行百度。

4、Build Steps(添加构建步骤)

这里选择EXecute NodeJS script

依此选择前面安装的node版本,npm配置文件,然后输入构建命令即可。

npm i 
npm run build:test

在这里插入图片描述

或者,使用构建命令
在这里插入图片描述

5、构建后操作

将构建完成后将build后的文件推送到服务器中,

1)选择Send build artifacts over SSH。

2)SSH Server:选择需要推送的目标服务器。(注意:这样需要到Dashboard > Manage Jenkins > System 中Publish over SSH先提前添加好服务器)

3)Transfers:Source files(需要传输的文件)、Remove prefix(不需要传输文件名前缀)Remote directory(如果存在,此文件夹将位于全局配置中的文件夹下方,如果不存在,将创建该文件夹。)
———————————————在这里插入图片描述

这样一套Vue的自动部署流程就配置好了。

凭据相关:

在这里插入图片描述

注意凭据类型
  • username and password
  • username and ssh key (pub、pri密钥文件)

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

构建后处理 step
在这里插入图片描述

Spring cloud 微服务,多实例(主备)部署 相关:

在这里插入图片描述
在这里插入图片描述

支持通过跳板机 穿透云ECS:
在这里插入图片描述

grep 命令:
在这里插入图片描述
在这里插入图片描述

nohup 命令: 会阻塞住
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
nohup 解决方案 :
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

nohup 另一种解决: dontKillMe 命令参数
在这里插入图片描述
亦或者
在这里插入图片描述
在这里插入图片描述

微服务部署:
在这里插入图片描述

构建 方式二 流水线脚本

front vue 前端部署

pipeline {
    agent any

    parameters {
        string(name: 'GIT_BRANCH', defaultValue: 'release', description: 'Git 分支')
        string(name: 'NODE_VERSION', defaultValue: '16.20.2', description: 'Node.js 版本(需与 Jenkins 全局工具名称匹配)')
    }

    environment {
        GIT_REPO      = 'http://192.168.21.3:1955/szkj/miany-mall/backend-ui.git'
        TARGET_SERVER = '192.168.21.4'
        DEPLOY_USER   = 'ltkj'
        DEPLOY_PATH   = '/www/wwwroot/static.ltkj.com/miany/backend_ui/'
        SSH_PORT      = '10022'
        DIST_DIR      = 'dist'
    }

    stages {
        stage('代码检出') {
            steps {
                echo "检出代码分支: ${params.GIT_BRANCH}"
                git branch: params.GIT_BRANCH,
                    url: env.GIT_REPO,
                    credentialsId: 'git-credentials'

                script {
                    def commitHash = sh(script: 'git rev-parse --short HEAD', returnStdout: true).trim()
                    env.COMMIT_HASH = commitHash
                    echo "当前提交: ${env.COMMIT_HASH}"
                }
            }
        }


        stage('构建') {
            steps {
                echo "使用 Node.js ${params.NODE_VERSION} 进行构建"
                // 修正点:使用正确的参数名 nodeJSInstallationName
                // nodejs(nodeJSInstallationName: "node-${params.NODE_VERSION}") {
                nodejs(nodeJSInstallationName: "${params.NODE_VERSION}") {
                    sh '''#!/bin/bash
                        set -e

                        echo "当前目录: $(pwd)"
                        echo "Node 版本: $(node -v)"
                        echo "NPM 版本: $(npm -v)"

                        # // TODO 这里不应该每次都 install 
                        if [ -f package-lock.json ]; then
                            npm ci
                        else
                            npm install
                        fi

                        if ! grep -q '"build:prodS"' package.json; then
                            echo "错误: package.json 中未找到 build:prodS 脚本"
                            exit 1
                        fi

                        npm run build:prodS

                        if [ ! -d "${DIST_DIR}" ]; then
                            echo "构建失败: 未找到 ${DIST_DIR} 目录"
                            exit 1
                        fi
                        echo "构建成功,${DIST_DIR} 目录内容:"
                        ls -lh ${DIST_DIR}
                    '''
                }
            }
        }

        stage('部署') {
            steps {
                
                echo "部署到 ${TARGET_SERVER}:${DEPLOY_PATH}"
                withCredentials([sshUserPrivateKey(
                    credentialsId: 'ltkj-ssh-key',
                    keyFileVariable: 'SSH_KEY'
                )]) {
                    // TODO 调试用 通过过后删除 >>>>>> 
                    sh '''#!/bin/bash
                        # // TODO 调试用 通过过后删除 >>>>>>
                        echo "调试用 通过过后删除 >>>>>> 私钥文件路径: $SSH_KEY"
                        ls -l "$SSH_KEY"
                        echo "私钥指纹(用于比对):"
                        ssh-keygen -lf "$SSH_KEY" || echo "无法读取指纹"
                        echo "对应的公钥内容(请复制并添加到服务器):"
                        ssh-keygen -y -f "$SSH_KEY" || echo "无法导出公钥"
                    '''
                
                    sh '''#!/bin/bash
                        set -e

                        SSH_OPTS="-i $SSH_KEY -p $SSH_PORT -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
                        REMOTE="${DEPLOY_USER}@${TARGET_SERVER}"

                        echo "确保远程目录存在: ${DEPLOY_PATH}"
                        ssh $SSH_OPTS $REMOTE "mkdir -p ${DEPLOY_PATH}"

                        echo "同步 ${DIST_DIR} 目录到服务器..."

                        # rsync -avz --delete --checksum \
                        #     -e "ssh $SSH_OPTS" \
                        #     ./${DIST_DIR} \
                        #     $REMOTE:${DEPLOY_PATH}/
                            
                        # TODO 还可以使用zip/unzip 提升传输效率
                        # 在本地打包,通过 SSH 管道传输,并在远程解压到指定目录
                        tar czf - ./${DIST_DIR} | ssh \$SSH_OPTS \$REMOTE "tar xzf - -C ${DEPLOY_PATH%/*}"

                        echo "远程目录内容预览:"
                        ssh $SSH_OPTS $REMOTE "ls -lh ${DEPLOY_PATH} | head -5"

                        echo "重载 Nginx 服务..."
                        // TODO 其实不需要重启reload nginx , 先改为查看
                        ssh $SSH_OPTS $REMOTE "
                            sudo systemctl status nginx || {
                                echo 'Reload 失败,尝试 restart...'
                                sudo systemctl restart nginx
                            }
                        "
                    '''
                }
            }
        }
    }

    post {
        always {
            archiveArtifacts artifacts: "${env.DIST_DIR}/**", fingerprint: true
        }
        failure {
            echo "❌ 部署失败!查看日志: ${env.JOB_URL}/${env.BUILD_NUMBER}/console"
        }
        success {
            echo "🎉 部署成功!项目已部署至 ${DEPLOY_PATH}"
            echo "👉 访问: http://static.ltkj.com/miany/backend_ui"
        }
    }
}

⚖️ 打包传输 vs rsync 对比

在这里插入图片描述

如果你的部署是全量替换(每次构建都生成全新的 dist),打包传输优势巨大;如果需要增量更新(只改动的文件),则需权衡。

🚀 在 Jenkins 中实现打包传输

方案一:使用 tar 通过 SSH 直接传输(推荐)
stage('部署 (打包传输)') {
    steps {
        withCredentials([sshUserPrivateKey(
            credentialsId: 'ltkj-ssh-key',
            keyFileVariable: 'SSH_KEY'
        )]) {
            sh """#!/bin/bash
                set -e
                SSH_OPTS="-i \$SSH_KEY -p $SSH_PORT -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
                REMOTE="${DEPLOY_USER}@${TARGET_SERVER}"

                echo "📦 打包 dist 目录并传输..."
                # 在本地打包,通过 SSH 管道传输,并在远程解压到指定目录
                tar czf - ./${DIST_DIR} | ssh \$SSH_OPTS \$REMOTE "tar xzf - -C ${DEPLOY_PATH%/*}"

                echo "✅ 传输完成,远程目录内容:"
                ssh \$SSH_OPTS \$REMOTE "ls -lh ${DEPLOY_PATH}"
            """
        }
    }
}
说明:
  • tar czf - ./dist:将 dist 目录打包并压缩(c 创建,z gzip压缩,f - 输出到标准输出)。
  • | ssh … “tar xzf - -C /目标/父目录”:通过 SSH 将压缩流发送到远程,并解压到指定目录的父目录(例如解压到 /www/…/miany/,会自动创建 dist 文件夹)。
  • %/* 是 Shell 参数扩展,用于获取父目录路径(假设 DEPLOY_PATH 为 /…/backend_ui/dist,则 %/* 结果为 /…/backend_ui)。

📊 效率实测参考

对一个典型的 Vue 项目(约 2000 个文件,总计 50MB):

  • rsync 无压缩:耗时 ~15 秒(主要花费在文件对比)。
  • rsync -z:耗时 ~10 秒(传输数据减少,但对比开销仍在)。
  • tar + ssh 打包传输:耗时 ~3 秒(一次流式传输,压缩率 ~70%)。

清理旧文件

打包传输是全量替换,不会自动删除远程多余的文件。如需清理,可在解压前先删除旧目录:

ssh \$SSH_OPTS \$REMOTE "rm -rf ${DEPLOY_PATH} && mkdir -p ${DEPLOY_PATH%/*}"

然后再执行 tar 管道。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐