jenkins通过pipeline部署springboot项目

部署方案:
1、springboot项目不保存部署的pipeline或dockerfile构建脚本等与部署相关的问文件,业务项目只需关心业务,能够正常构建为jar包即可
2、新建一个代码仓库,用于保存项目需要构建的Jenkinsfile
3、jenkins配置pipeline地址,从仓库拉取要构建的项目进行构建和部署
构建文件仓库示例结构如下:
在这里插入图片描述
4、jenkins配置
在这里插入图片描述
5、springboot项目镜像构建文件

# 指定基础镜像,这是分阶段构建的前期阶段
FROM eclipse-temurin:21-jre-alpine as builder

# 设定时区、中文
ENV TZ=Asia/Shanghai
# 安装chrony包
RUN apk add --no-cache chrony

# 配置chrony
RUN echo "server 0.pool.ntp.org iburst" >> /etc/chrony/chrony.conf
RUN echo "server 1.pool.ntp.org iburst" >> /etc/chrony/chrony.conf
RUN echo "server 2.pool.ntp.org iburst" >> /etc/chrony/chrony.conf
RUN echo "server 3.pool.ntp.org iburst" >> /etc/chrony/chrony.conf

# 执行工作目录
WORKDIR application
# 配置参数
ARG JAR_FILE=target/*.jar
# 将编译构建得到的jar文件复制到镜像空间中
COPY ${JAR_FILE} application.jar
# 通过工具spring-boot-jarmode-layertools从application.jar中提取拆分后的构建结果
RUN java -Djarmode=layertools -jar application.jar extract
# 启动chronyd服务
CMD ["chronyd"]

# 正式构建镜像
FROM builder
WORKDIR application
# 前一阶段从jar中提取除了多个文件,这里分别执行COPY命令复制到镜像空间中,每次COPY都是一个layer
COPY --from=builder application/dependencies/ ./
COPY --from=builder application/spring-boot-loader/ ./
COPY --from=builder application/snapshot-dependencies/ ./
COPY --from=builder application/application/ ./
# ENTRYPOINT  ["java", "org.springframework.boot.loader.JarLauncher"]
# 分层构建传递参数写法
ENTRYPOINT  ["sh","-c","java  $JAVA_OPTS org.springframework.boot.loader.JarLauncher $PARAMS"]

# 新新
# 例如: docker run -d -p 21991:2199 --name demo3 -e JAVA_OPTS="-Xmx128m"  -e PARAMS="--spring.application.name=test-demo" docker-demo:1.3
#镜像放在最后,所传的java参数和覆盖配置文件参数写在docker镜像之前不然会导致传递失败

基础镜像可选择:

openjdk:21-jdk
openjdk:21-slim
# 基于dibian构建
 bitnami/minideb

6、demo项目docker-compose.yml文件

services:
  demo:
    #  启动时传入镜像tag示例:BUILD_TAG=20240406-57 docker-compose up -d
    image: registry.cn-guangzhou.aliyuncs.com/lyr-test/demo:${BUILD_TAG}
    container_name: demo
    restart: always
    network_mode: host
    deploy:
      resources:
        limits:
          cpus: '1.00'
          memory: 1G
        reservations:
          cpus: '0.10'
          memory: 256M
    environment:
      - JAVA_OPTS= -XX:+UseContainerSupport -XX:InitialRAMPercentage=75.0 -XX:MaxRAMPercentage=75.0 -XX:MinRAMPercentage=75.0
      # 当network_mode使用hots模式时,端口号设置不生效
      - PARAMS = --server.port=8080

7、Jenkinsfile构建文件

// 获取当前日期
def current_date = new Date().format('yyyyMMdd')
// 获取当前构建号
def build_number = env.BUILD_NUMBER.toInteger()
// 服务器集合
def server_list = []
// 所有的脚本命令放在pipeline中
pipeline {
    // 指定任务在哪个集群节点中执行,any表示任意节点
    agent any

    parameters {
        string(description: '代码分支', name: 'CODE_BRANCH_PARAM', defaultValue: 'master', trim: true)
        // 这在Jenkins的凭据里设置的待部署服务器的名称就是服务器的ip;用docker-compose部署一般只会部署几台服务器,如果量大,建议上k8s
        booleanParam defaultValue: true, description: '10.0.24.8', name: 'SERVER_1'
        booleanParam description: '10.0.24.3', name: 'SERVER_2'
    }

    tools {
        git 'Default'
    }

    // 声明全局变量,方便后面修改使用
    environment {
        GIT_CONFIG_BRANCH = "master"
        GIT_CONFIG_ADDRESS = "https://*******/demo-jenkins.git"
        CODE_ADDRESS = "https://********/demo.git"
        // jenkins中创建的代码仓库密钥id
        CREDENTIALS_ID = 'git-credentials-id'
        IMG_REPO_CREDENTIALS_ID = 'img-repo-credentials-id'
        IMG_REPO = "registry.cn-guangzhou.aliyuncs.com"
        REPO_NAMESPACE = 'lyr-test'
        DEFAULT_BUILD_TAG = "${current_date}-${build_number}"
    }

    stages {
        stage('环境检测') {
            steps {
                // 构建环境检测
                sh '''
                     cat /proc/version
                     free -m
                     df -h
                     docker -v
                     git -v
                     mvn -v
                     java -version
                   '''
                echo '环境检测完成'
            }
        }
        stage('拉取配置文件') {
            steps {
                echo "拉取配置文件代码分支:${GIT_CONFIG_BRANCH}"
                sh "pwd"
                dir('/var/jenkins_home/workspace/pipeline/') {
                    sh "pwd"
                    echo "${CREDENTIALS_ID}"
                    checkout scmGit(branches: [[name: "${GIT_CONFIG_BRANCH}"]], extensions: [], userRemoteConfigs: [[credentialsId: "${CREDENTIALS_ID}", url: "${GIT_CONFIG_ADDRESS}"]])
                }
                sh "pwd"
            }
        }
        stage('拉取代码') {
            steps {
                echo pwd
                // BRANCH为构建分支参数
                git branch: "${CODE_BRANCH_PARAM}", credentialsId: "${CREDENTIALS_ID}", url: "${CODE_ADDRESS}"
            }
        }
        stage('maven构建') {
            steps {
                echo pwd
                sh """
                  mvn clean package -U -Dmaven.test.skip=true
                """
            }
        }
        stage('生成镜像') {
            steps {
                echo pwd
                // JOB_NAME为项目名变量(内置的环境变量) TAG为设置的变量标签
                sh '''
                 cp /var/jenkins_home/workspace/pipeline/${JOB_NAME}/Dockerfile /var/jenkins_home/workspace/${JOB_NAME}
                '''
                script {
                    echo "当前镜像tag:${DEFAULT_BUILD_TAG}"
                    sh "docker build -f Dockerfile  -t ${IMG_REPO}/${REPO_NAMESPACE}/${JOB_NAME}:${DEFAULT_BUILD_TAG} ."
                }
            }
        }
        stage('推送镜像') {
            steps {
                withCredentials([usernamePassword(credentialsId: 'img-repo-credentials-id', passwordVariable: 'IMG_PWD', usernameVariable: 'IMG_USER')]) {
                    sh '''
               	       echo "${IMG_PWD}" | docker login --username ${IMG_USER} --password-stdin ${IMG_REPO}
                       docker image prune -f
                       docker push ${IMG_REPO}/${REPO_NAMESPACE}/${JOB_NAME}:${DEFAULT_BUILD_TAG}
                    '''
                }
            }

        }
        stage('清理') {
            steps {
                sh '''
               	# 退出镜像仓库
               # docker logout ${IMG_REPO}
                # 清理前镜像
               # docker images
                # 删除指定镜像
               # docker rmi ${IMG_REPO}/${REPO_NAMESPACE}/${JOB_NAME}:${PRE_BUILD_TAG}
                # 命令删除,删除最早一个
               # docker images | grep "demo" | sort -r | tail -n 1 | awk '{print $3}'  | xargs docker rmi
                # 清理后镜像
                docker images
                '''
            }
        }
        stage('部署至服务器') {
            steps {
                script {
                    script {
                        echo "SERVER_1:" + SERVER_1
                        if (SERVER_1=="true") {
                            server_list.add('10.0.24.8')
                        }
                        echo "SERVER_2:" + SERVER_2
                        if (SERVER_2=="true") {
                            server_list.add('10.0.24.3')
                        }
                        for (server_ip in server_list) {
                            echo "当前部署的服务器id:${server_ip}"
                            withCredentials([usernamePassword(credentialsId: server_ip, passwordVariable: 'SERVER_PWD', usernameVariable: 'SERVER_USER')]) {
                                node {
                                    def remote = [:]
                                    remote.name = "deploy"
                                    remote.host = server_ip
                                    remote.user = "${SERVER_USER}"
                                    remote.password = "${SERVER_PWD}"
                                    remote.allowAnyHosts = true
                                    stage('远程ssh部署') {
                                        echo "当前远程ssh部署的项目名:${JOB_NAME}"
                                        sshCommand remote: remote, command: "mkdir -p /data/${JOB_NAME}"
                                        sshPut remote: remote, from: """/var/jenkins_home/workspace/pipeline/${JOB_NAME}/docker-compose.yaml""", into: """/data/${JOB_NAME}"""
                                        sshCommand remote: remote, command: """
                                            cd /data/${JOB_NAME}/
                                            BUILD_TAG=${DEFAULT_BUILD_TAG} docker-compose up -d
                                            docker-compose ps
                                        """
                                        echo "ssh部署脚本执行完成"
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    // 通知内容
    post {
        success {
            //成功通知
            echo "成功通知"

        }
        failure {
            // 失败通知
            echo "失败通知"
        }
    }
}

8、jenkins中配置Jenkinsfile中使用到的代码仓库凭据,镜像仓库凭据和服务器密码凭据
在这里插入图片描述
9、配置完成后,点击构建就行
在这里插入图片描述
10、当首次部署到新服务器时,需要登录镜像仓库,可以手动登录,也可以在jenkins中进行配置,每次发布都要登录,不然会拉取镜像错误

// 服务器集合
def server_list = []
// 所有的脚本命令放在pipeline中
pipeline {
    // 指定任务在哪个集群节点中执行,any表示任意节点
    agent any

    parameters {
        choice(description: '服务名', name: 'SERVICE_NAME', choices: ["demo"])
        string(description: '镜像tag', name: 'BUILD_TAG_PARAM', defaultValue: '20240405-01', trim: true)
        booleanParam defaultValue: true, description: '10.0.24.8', name: 'SERVER_1'
        booleanParam description: '10.0.24.3', name: 'SERVER_2'
    }

    tools {
        git 'Default'
    }

    // 声明全局变量,方便后面修改使用
    environment {
        GIT_CONFIG_BRANCH = "master"
        GIT_CONFIG_ADDRESS = "https://******/demo-jenkins.git"
        // jenkins中创建的代码仓库密钥id
        CREDENTIALS_ID = 'git-credentials-id'
        IMG_REPO_CREDENTIALS_ID = 'img-repo-credentials-id'
        IMG_REPO = "registry.cn-guangzhou.aliyuncs.com"
        REPO_NAMESPACE = 'lyr-test'
    }

    stages {
        stage('环境检测') {
            steps {
                // 构建环境检测
                sh '''
                     cat /proc/version
                     free -m
                     df -h
                     docker -v
                     git -v
                     mvn -v
                     java -version
                   '''
                echo '环境检测完成'
            }
        }
        stage('拉取配置文件') {
            steps {
                echo "拉取配置文件代码分支:${GIT_CONFIG_BRANCH}"
                sh "pwd"
                dir('/var/jenkins_home/workspace/pipeline/') {
                    sh "pwd"
                    echo "${CREDENTIALS_ID}"
                    checkout scmGit(branches: [[name: "${GIT_CONFIG_BRANCH}"]], extensions: [], userRemoteConfigs: [[credentialsId: "${CREDENTIALS_ID}", url: "${GIT_CONFIG_ADDRESS}"]])
                }
                sh "pwd"
            }
        }
        stage('登录镜像') {
            steps {
                withCredentials([usernamePassword(credentialsId: 'img-repo-credentials-id', passwordVariable: 'IMG_PWD', usernameVariable: 'IMG_USER')]) {
                    script {
                        echo "SERVER_1:" + SERVER_1
                        if (SERVER_1=="true") {
                            server_list.add('10.0.24.8')
                        }
                        echo "SERVER_2:" + SERVER_2
                        if (SERVER_2=="true") {
                            server_list.add('10.0.24.3')
                        }
                        for (server_ip in server_list) {
                            echo "当前部署的服务器id:${server_ip}"
                            withCredentials([usernamePassword(credentialsId: server_ip, passwordVariable: 'SERVER_PWD', usernameVariable: 'SERVER_USER')]) {
                                node {
                                    def remote = [:]
                                    remote.name = "deploy"
                                    remote.host = server_ip
                                    remote.user = "${SERVER_USER}"
                                    remote.password = "${SERVER_PWD}"
                                    remote.allowAnyHosts = true
                                    stage('远程ssh部署') {
                                        echo "当前远程ssh登录的服务器ip:${server_ip}"
                                        sshCommand remote: remote, command: """
                                            echo "${IMG_PWD}" | docker login --username ${IMG_USER} --password-stdin ${IMG_REPO}
                                        """
                                        echo "镜像ssh部署脚本执行完成"
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        stage('部署至服务器') {
            steps {
                script {
                    script {
                        echo "SERVER_1:" + SERVER_1
                        if (SERVER_1=="true") {
                            server_list.add('10.0.24.8')
                        }
                        echo "SERVER_2:" + SERVER_2
                        if (SERVER_2=="true") {
                            server_list.add('10.0.24.3')
                        }
                        for (server_ip in server_list) {
                            echo "当前部署的服务器id:${server_ip}"
                            withCredentials([usernamePassword(credentialsId: server_ip, passwordVariable: 'SERVER_PWD', usernameVariable: 'SERVER_USER')]) {
                                node {
                                    def remote = [:]
                                    remote.name = "deploy"
                                    remote.host = server_ip
                                    remote.user = "${SERVER_USER}"
                                    remote.password = "${SERVER_PWD}"
                                    remote.allowAnyHosts = true
                                    stage('远程ssh部署') {
                                        echo "当前远程ssh部署的项目名:${SERVICE_NAME}"
                                        sshCommand remote: remote, command: "mkdir -p /data/${SERVICE_NAME}"
                                        sshPut remote: remote, from: """/var/jenkins_home/workspace/pipeline/${SERVICE_NAME}/docker-compose.yaml""", into: """/data/${SERVICE_NAME}"""
                                        sshCommand remote: remote, command: """
                                            cd /data/${SERVICE_NAME}/
                                            BUILD_TAG=${BUILD_TAG_PARAM} docker-compose up -d
                                            docker-compose ps
                                        """
                                        echo "ssh部署脚本执行完成"
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    // 通知内容
    post {
        success {
            //成功通知
            echo "成功通知"

        }
        failure {
            // 失败通知
            echo "失败通知"
        }
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Element ui 动态展示表格列,动态格式化表格列的值

需求 后台配置前端展示的表格列,遇到比如 文件大小这样的值,如果后台存的是纯数字,需要进行格式化展示,并且能控制显示的小数位数,再比如,部分列值需要加单位等信息,此外还有状态类&#xff0…

【心路历程】初次参加蓝桥杯实况

送给大家一句话: 寂静的光辉平铺的一刻,地上的每一个坎坷都被映照得灿烂。 – 史铁生 《我与地坛》 初次参加蓝桥杯有感 一点小小的震撼难评的做题过程A题 艺术与篮球问题描述解题 B 题 五子棋问题描述解题 C题 训练士兵问题描述解题 D题 团建解题 E题 …

基于SpringBoot+Vue的毕业设计管理系统(源码+文档+部署+讲解)

一.系统概述 二十一世纪我们的社会进入了信息时代,信息管理系统的建立,大大提高了人们信息化水平。传统的管理方式对时间、地点的限制太多,而在线管理系统刚好能满足这些需求,在线管理系统突破了传统管理方式的局限性。于是本文针…

【前端】layui table表格勾选事件,以及常见模块

欢迎来到《小5讲堂》,大家好,我是全栈小5。 这是《前端》系列文章,每篇文章将以博主理解的角度展开讲解, 温馨提示:博主能力有限,理解水平有限,若有不对之处望指正! 目录 表格勾选事…

接口测试-Mock测试方法详解

🍅 视频学习:文末有免费的配套视频可观看 🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 一、关于Mock测试 1、什么是Mock测试? Mock 测试就是在测试过程中,对于…

Vue3整合wangEditor(富文本编辑器框架) 以及提供存储渲染方案

目录 概述 Vue3整合wagnEditor 图片的上传 图片的删除 文章存储 文章渲染 概述 实现功能:管理端使用富文本编辑器编写文章内容,将编辑好的文章存入数据库或服务器中,前端应用读取存储的文章内容作展示。 本文章能提供 ①Vue3整合wangEdi…

一款免费、开源、可批量识别的离线OCR软件,适用于 Windows7 x64及以上平台

免费:本项目所有代码开源,完全免费。方便:解压即用,离线运行,无需网络。高效:自带高效率的离线OCR引擎,内置多种语言识别库。灵活:支持命令行、HTTP接口等外部调用方式。功能&#x…

Android开发——控件

目录 TextView 注意: ​编辑带阴影的textview:(一般用于给字体添加属性) ​编辑 跑马灯效果的textview​编辑 Button (前几个常用) Botton事件处理 EditText (文本框) 如何获取文本框里面的内容…

统计学习方法概述

一、引言 随着AI的曙光逐渐普照IT界,众多曾经高深莫测的人工智能术语与理念,如监督学习、算法模型、回归分析等,已悄然融入广大信息技术人员的知识体系之中。老猿是个很传统的IT人,虽未深究这些新兴知识的精髓,却也在…

从零开始编写一个cmake构建脚本

简介 本文档介绍cmake构建脚本编写,包含的一些主要元素和命名规范。 cmake构建脚本编写步骤 cmake构建工具版本要明确 # 命令名字要小写,这条语句要求构建工具至少需要版本为3.12或以上 cmake_minimum_required (VERSION 3.12)工程名及库的版本号明确…

阿里面试总结 一

写了这些还是不够完整,阿里 字节 卷进去加班!奥利给 ThreadLocal 线程变量存放在当前线程变量中,线程上下文中,set将变量添加到threadLocals变量中 Thread类中定义了两个ThreadLocalMap类型变量threadLocals、inheritableThrea…

深度学习的模型有几类,能干嘛用?

1、基础模型 (1)卷积神经网络 **卷积:**卷积的本质是通过矩阵运算9的方式将输入数据进行空间上的滤波,有效地提取数据中的局 部特征,从而实现特征数据更高程度的抽象表示。 **池化:**可以理解成“压缩”…

火绒安全软件:程序员的网络守护天使

目录 前言 系统防护 网络防护 隐私保护 高级设置 软件安全 响应速度 持续更新 总结 前言 在这个充满机遇与挑战的数字时代,程序员们如同探险家,不断探索着代码的新大陆。然而,网络世界也充斥着各种未知的风险和威胁。火绒安全软件&a…

浏览器工作原理与实践--渲染流水线:CSS如何影响首次加载时的白屏时间

在上一篇文章中我们详细介绍了DOM的生成过程,并结合具体例子分析了JavaScript是如何阻塞DOM生成的。那本文我们就继续深入聊聊渲染流水线中的CSS。因为CSS是页面中非常重要的资源,它决定了页面最终显示出来的效果,并影响着用户对整个网站的第…

初识 QT

初始QT 什么是QTQT发展史QT支持的平台QT的优点QT的应用场景搭建QT开发环境QT的开发工具概述QT下载安装 使用QT创建项目QT 实现Hello World程序使用按钮控件来实现使用标签控件来实现 项目文件解析widget.hmain.cppwidget.cppwidget.ui.pro文件 对象树QT 窗口坐标体系 什么是QT …

STM32H7的MPU学习和应用示例

STM32H7的MPU学习记录 什么是MPU?MPU的三种内存类型内存映射MPU保护区域以及优先级 MPU的寄存器XN位AP位TEX、C、B、S位SRD 位SIZE 位CTRL 寄存器的各个位 示例总结 什么是MPU? MPU(Memory Protection Unit,内存保护单元&#xf…

LeetCode最长有效括号问题解

给定一个仅包含字符的字符串(’ 和 ‘)’,返回最长有效的长度(出色地-形成) 括号子弦。 示例1: 输入:s “(()” 输出:2 说明:最长的有效括号子字符串是 “()” 。 示例2: 输入:s “)()())…

5分钟手把手教你 Guitar Pro v8.1.1 Build 17 中文完整激活版(附教程) 64位

吉他爱好者必备神器:Guitar Pro v8.1.1 Build 17深度解析 随着数字音乐制作和学习的日益普及,越来越多的吉他爱好者开始寻找能够帮助他们提升技能、创作音乐的专业工具。在众多吉他制作软件中,Guitar Pro因其强大的功能和易用的界面备受推崇…

Linux内核中KASLR功能是什么?有什么作用?怎么破除?以及如何实操?(地址空间、layout random、kallsyms)

1. 背景 KASLR是一个什么技术点其实不重要,但重要的是有了KASLR这个功能后,造成内核中某个符号(函数 or 变量)在System.map中的地址和实际不一样了(实际: cat /proc/kallsyms),进一…

JVM性能调优——GC日志分析

文章目录 1、概述2、生成GC日志3、Parallel垃圾收集器日志解析3.1、Minor GC3.2、FULL GC 4、G1垃圾收集器日志解析4.1、Minor GC4.2、并发收集4.3、混合收集4.4、Full GC 5、CMS垃圾收集器日志解析5.1、Minor GC5.2、Major GC5.3、浮动垃圾 6、日志解析工具6.1、GCeasy6.2、GC…