jenkins 部署应用到多个环境

news2024/9/22 23:36:30

在日常开发的过程中,我们经常会遇到将应用程序部署到多个环境的需求场景,如会先发布到测试环境,由测试人员进行测试,成功之后,会继续将当前应用部署到集成环境,进行集成测试,全部通过后,再继续将应用部署到生产环境,即完成一整个上线的流程。

本文将介绍如何基于流水线的方式,将应用部署到多个环境,本次之多两个环境,分别是测试环境和生产环境,可以根据实际情况进行优化调整。

创建项目

如上,创建一个流水线的项目

设置参数

如上图所示,设置一个标识参数,是否部署到生产环境

配置流水线

流水线的配置,如下图所示,是整个项目配置的核心所在,我们需要在此处设置项目构建工具maven,拉取项目代码,构建项目代码,将打包后的文件上传到部署的服务器上,在远程服务器上启动应用以及最后的清理等步骤。

设置环境变量

设置环境变量是为了将之前配置的参数写到环境变量中,供后续阶段使用

environment {
        DEPLOY_TO_PROD = "${params.deployToProd}"
    }

以上配置之后,后续便可以通过env.DEPLOY_TO_PROD进行引用。

配置maven

tools {
        maven "maven"
    }

以上配置了项目的构建工具maven,maven的值是之前在全局设置中配置的,可参考之前的文章。

构建

stages {

}

配置了构建的阶段,可以在里面配置多个stage代码块,每个块代表一个阶段,如构建、部署测试、部署生产等。

构建项目阶段

在构建阶段,我们拉取代码,并使用maven进行构建,构建成功后,将构建成功的包进行归档,供后续阶段使用

stage('构建') {
            steps {
                // Get some code from a GitHub repository
                git branch: 'main', credentialsId: 'git', url: 'http://ip:port/projectName.git'

                // Run Maven on a Unix agent.
                sh "mvn -Dmaven.test.skip=true clean package"
            }

            post {
                // If Maven was able to run the tests, even if some of the test
                // failed, record the test results and archive the jar file.
                success {
                    archiveArtifacts 'target/*.jar'
                    archiveArtifacts 'Dockerfile'
                }
            }
        }

在stage中,通过steps配置当前阶段的构建步骤,在上述片段中,先拉取代码,并使用mvaven进行构建。post片段是在maven执行成功后进行构建,我们将项目构建成功后的jar包以及项目根目录下的Dockerfile进行归档。在下一个步骤中,会将归档后的文件上传到部署的服务器中。

部署测试环境

在将项目的部署文件归档后,便可以部署到测试环境了,片段如下

在上个阶段,我们配置的是部署到测试环境,首先使用ssh over publisher插件,将归档的构建上传到服务器,在post中,设置了success 片段,是在上传成功后执行的片段,在此我们使用sh 命令,在远程服务器上执行命令,本项目使用了docker,因此,ssh中的命令都是关于docker的,大家可以根据实际情况,进行调整。此外,需要注意 ssh -o StrictHostKeyChecking=no root@ip,其中ip是远程服务器的ip地址,需要提前配置私匙,之前文章有讲解,可以参考下。此处,无须设置密码的操作。

部署生产环境

在部署生产环境时,需要判断环境变量DEPLOY_TO_PROD是否符合条件,如果符合,则执行生产阶段的代码,否则不执行。如下图所示

本例子中,实在生产环境部署了两台服务器,因此sshPublisher是两个,而在post中,使用了script脚本,因为要操作两台服务器,变脸执行每台服务器的命令,大家可以根据需要调整。

清理阶段

post {
        always {
            // 清理工作空间
            cleanWs()
        }
    }

如上,执行部署完成后的清理操作。

整体代码如下:

pipeline {
    agent any
    parameters {
        choice(
            name: 'deployToProd',
            choices: ['否','是'],
            description: "如果需要部署到生产,选择【是】"
        )
    }

    environment {
        DEPLOY_TO_PROD = "${params.deployToProd}"
    }

    tools {
        // Install the Maven version configured as "M3" and add it to the path.
        maven "maven"
    }

    stages {
        stage('构建') {
            steps {
                // Get some code from a GitHub repository
                git branch: 'main', credentialsId: 'git', url: 'http://ip:port/projectName.git'

                // Run Maven on a Unix agent.
                sh "mvn -Dmaven.test.skip=true clean package"
            }

            post {
                // If Maven was able to run the tests, even if some of the test
                // failed, record the test results and archive the jar file.
                success {
                    archiveArtifacts 'target/*.jar'
                    archiveArtifacts 'Dockerfile'
                }
            }
        }
        
        
        stage("测试") {
            steps {
                sshPublisher(publishers: [sshPublisherDesc(configName: 'ss', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: 'echo "s"', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: 'refine', remoteDirectorySDF: false, removePrefix: '', sourceFiles: 'target/*.jar'), sshTransfer(cleanRemote: false, excludes: '', execCommand: 'echo "Success"', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: 'refine', remoteDirectorySDF: false, removePrefix: '', sourceFiles: 'Dockerfile')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
            }
            post {
                success {
                    sh '''
                        ssh -o StrictHostKeyChecking=no root@remote_ip "
                            cd /app/dir

                        "
                    '''
                }
            }
        }
        

        stage('线上环境') {
            when {
                expression { return env.DEPLOY_TO_PROD == '是' }
            }
            steps {
                sshPublisher(publishers: [sshPublisherDesc(configName: '10_202', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: 'echo "s"', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: 'refine', remoteDirectorySDF: false, removePrefix: '', sourceFiles: 'target/*.jar'), sshTransfer(cleanRemote: false, excludes: '', execCommand: 'echo "s"', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: 'refine', remoteDirectorySDF: false, removePrefix: '', sourceFiles: 'Dockerfile')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
                sshPublisher(publishers: [sshPublisherDesc(configName: '10_201', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: 'echo "s"', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: 'refine', remoteDirectorySDF: false, removePrefix: '', sourceFiles: 'target/*.jar'), sshTransfer(cleanRemote: false, excludes: '', execCommand: 'echo "s"', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: 'refine', remoteDirectorySDF: false, removePrefix: '', sourceFiles: 'Dockerfile')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
            }
            post {
                success {
                    script {
                        def servers = ['remote_ip1','remote_ip2']
                        servers.each { server ->
                            echo "Processing server: ${server}"
                            sh """
                                ssh -o StrictHostKeyChecking=no root@${server} "
                                cd /home/app/dir
                                # 其他linux命令
                                "
                            """
                        }
                    }
                }
                
            }
        }
    }
    post {
        always {
            // 清理工作空间
            cleanWs()
        }
    }
}

以上是完成的流水线代码,大家可以根据实际情况进行调整。

部署效果,如上图所示!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2117354.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

单位权中误差 详细介绍

单位权中误差(Unit Weight Error, UWE)是用于描述测量数据不确定性的一个统计量,特别是在地理信息系统(GIS)、导航和定位系统中。它主要用于评估和比较不同测量系统或算法的精度。以下是对单位权中误差的详细介绍&…

C++第一节入门

一、历史 C是在C上继承拓展的! java是一家公司(甲骨文)借鉴C生成的! C#是微软借鉴java生成的! 二、命名空间 当我们定义一个名叫rand的变量,但是由于stdlib头文件里面有个函数跟rand重名!因此…

如何在 Linux 系统中禁用用户登录 ?

管理 Linux 系统上的帐户是系统管理员的一项重要任务。一个常见的任务是禁用帐户,由于各种原因可能需要禁用帐户,例如当员工离开公司或出于安全目的需要临时禁用访问时。 本指南将以简单易懂的步骤引导您完成在 Linux 系统上禁用帐户的过程。 Step 1: …

Ruoyi Cloud 本地启动

参考 http://doc.ruoyi.vip/ https://gitee.com/y_project/RuoYi-Cloud https://blog.csdn.net/cs_dnzk/article/details/135289966 https://doc.ruoyi.vip/ruoyi-cloud/cloud/seata.html#%E5%9F%BA%E6%9C%AC%E4%BB%8B%E7%BB%8D 拉取代码本地跑通 用 git 从 ruoyi 微服务版仓…

HCIA--实验十一:单区域OSPF路由实验

一、实验内容 1.需求/要求: 使用三个路由器互联,各自配置一个loopback接口,在三个路由器上配置ospf动态路由协议; 二、实验过程 1.拓扑图: 2.步骤: 1.router配置基本信息 各接口的ip地址、loopback接…

华为OD机试真题 - 特殊的加密算法 - 深度优先搜索DFS(Python/JS/C/C++ 2024 D卷 200分)

华为OD机试 2024E卷题库疯狂收录中,刷题点这里 专栏导读 本专栏收录于《华为OD机试真题(Python/JS/C/C)》。 刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,…

C++:priority_queue(优先级队列)的模拟实现

目录 一、什么是优先级队列 二、优先级队列的定义 三、优先级队列的常用接口 四、模拟实现一个优先级队列 1、posh接口 2、empty接口、size接口和top接口 3、pop接口 4、构造函数 五、整体代码 一、什么是优先级队列 首先优先级队列不是队列,C 中的优先队…

IP包头的总长度字段和UDP包头的长度字段之间的关系

IP包头的总长度字段和UDP包头的长度字段之间的关系,并通过实例加以说明。 IP包头的总长度字段 **总长度(Total Length)**字段是一个16位的字段,表示整个IP数据包的总长度,包括IP包头和数据部分。单位是字节。由于该字…

AI一键生成 PPT

AI一键生成 PPT 操作步骤 作为一名打工人,是不是经常需要制作各种PPT来分享我的生活和想法。但是,你们知道,有时候灵感来了,时间却不够用了!😩直到我发现了Kimi AI——一个能够自动生成PPT的神奇助手&#…

PID控制算法(二)

&#xff08;BIlibili借鉴&#xff09;PID参数整定连接&#xff1a;Webpack App (rossning92.github.io) C的基本程序代码&#xff1a; 借鉴链接&#xff1a;PID超详细教程——PID原理串级PIDC代码在线仿真调参-CSDN博客 #include <iostream>using namespace std;stru…

【信创】统信UOS桌面UT-2024-0027漏洞修复

原文链接&#xff1a;【信创】统信UOS系统UT-2024-0027漏洞修复 Hello&#xff0c;大家好啊&#xff01;今天给大家带来一篇关于统信UOS桌面操作系统UT-2024-0027漏洞修复的文章。漏洞修复是确保系统安全性的重要步骤&#xff0c;及时更新和修复系统中的安全漏洞&#xff0c;可…

大数据之Flink(三)

9.3、转换算子 9.3.1、基本转换算子 9.3.1.1、映射map 一一映射 package transform;import bean.WaterSensor; import org.apache.flink.streaming.api.datastream.DataStreamSource; import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator; impor…

Go开源日志库Logrus的使用

一、Logrus简介 Logrus 是一个流行的 Go 语言日志库&#xff0c;以其功能强大、性能高效和高度灵活性而闻名。有关更多介绍可查看 Logrus。 主要特点 丰富的日志级别&#xff1a;Logrus 支持多种日志级别&#xff0c;包括 Debug、Info、Warn、Error、Fatal 和 Panic&#xf…

深入理解数据库的 4NF:多值依赖与消除数据异常

在数据库设计中&#xff0c; "范式" 是一个常常被提到的重要概念。许多初学者在学习数据库设计时&#xff0c;经常听到第一范式&#xff08;1NF&#xff09;、第二范式&#xff08;2NF&#xff09;、第三范式&#xff08;3NF&#xff09;以及 BCNF&#xff08;Boyce-…

RESTful 还是 JSON-RPC

前言 RESTful 比较简单地说就是&#xff0c;大家请求一样的url&#xff08;GET方法有一个例外&#xff0c;url中带了一个id&#xff09;&#xff0c;通过不同的请求方法&#xff0c;分别进行不同的操作&#xff08;CRUD&#xff09;。 JSON-RPC JSON-RPC是一个无状态且轻量级…

SpringBoot学习(7)(Bean对象注册)(自定义组合注解)

目录 一、引言 二、案例学习 &#xff08;一&#xff09;Bean &#xff08;二&#xff09;Import 三、补充 &#xff08;1&#xff09;关于Java中collection.toArray(new String[0])解释 &#xff08;2&#xff09;组合注解 一、引言 上次学习了解到&#xff0c;springb…

基于机器学习的阿尔兹海默症智能分析预测系统

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长 QQ 名片 :) 1. 项目简介 阿尔兹海默症&#xff08;Alzheimers Disease, AD&#xff09;是一种常见的神经退行性疾病&#xff0c;主要影响老年人的认知功能。随着全球人口老龄化的加剧&#xff0c;阿尔兹海默症的患病率逐年…

nodejs 使用kafka案例,node-red配置kafka案例,从安装配置kafka开始

生产者测试&#xff1a; bin/kafka-console-producer.sh --broker-list 1.2.3.4:9092 --topic test-topic消费者测试&#xff1a; bin/kafka-console-consumer.sh --bootstrap-server 1.2.3.4:9092 --topic test-topic --from-beginningconst { Kafka } require(kafkajs)con…

【AIGC数字人】EchoMimic:基于可编辑关键点条件的类人音频驱动肖像动画

GitHub&#xff1a;https://github.com/BadToBest/EchoMimic 论文&#xff1a; https://arxiv.org/pdf/2407.08136 comfyui&#xff1a; https://github.com/smthemex/ComfyUI_EchoMimic 相关工作 Wav2Lip Wav2Lip是一个开创性的工作 &#xff0c;但输出会出现面部模糊或扭…