jenkins通过pipeline部署springboot项目

news2024/12/24 0:04:29

部署方案:
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镜像之前不然会导致传递失败

基础镜像可选择:

eclipse-temurin:21-jre-alpine
eclipse-temurin:21-jdk-alpine
openjdk:21
openjdk:21-slim
# 基于dibian构建
 bitnami/minideb
 debian:bullseye-slim

在这里插入图片描述

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 "失败通知"
        }
    }
}

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

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

相关文章

一文了解OCI标准、runC、docker、contianerd、CRI的关系

docker和contanerd都是流行的容器运行时(container runtime);想讲清楚他们两之间的关系,让我们先从runC和OCI规范说起。 一、OCI标准和runC 1、OCI(open container initiative) OCI是容器标准化组织为了…

【C++】力扣OJ题:构建杨辉三角

Hello everybody!今天给大家介绍一道我认为比较经典的编程练习题&#xff0c;之所以介绍它是因为这道题涉及到二维数组的构建&#xff0c;如果用C语言动态构建二维数组是比较麻烦的&#xff0c;而用C中STL的vector<vector<int>>,就可以立马构建出来&#xff0c;这也…

【前端】2. HTML综合案例

1. 展示简历信息 代码如下&#xff1a;可自行发挥 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>个…

【C++学习】map和set

目录 一、关联式容器 二、键值对 三、树形结构的关联式容器 四、set 4.1 set的介绍 4.2 set的使用 4.2.1 set的模板参数列表 4.2.2 set的构造 4.2.3 set的容量 4.2.4 set修改操作 4.2.5 set的使用举例 五、map 5.1 map的介绍 5.2 map的使用 5.2.1 map的模板参数说…

高级感拉满的个人UI网页

效果图 PC端 移动端 部分代码 index.html <!DOCTYPE html> <html><head><meta charset"utf-8" /><title>Zboy的主页</title><link rel"stylesheet" href"css/normalize.css" /><link rel&qu…

C语言-输入数,存入数组,将奇数放置数组左侧,将偶数放置数组右侧

一 主要涉及到的知识点: 1.1 for循环 1.2 计算数组的大小int sz sizeof(arr) / sizeof(arr[0]); 1.3 函数的定义使用 1.4 while()循环 二 源代码: //输入一个整数数组,实现一个函数 //来调整该数组中数字的顺序使得数组中所有的奇数位与数组的前半部分, //所有的偶数位于…

Springboot+Vue项目-基于Java+MySQL的蜗牛兼职网系统(附源码+演示视频+LW)

大家好&#xff01;我是程序猿老A&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;Java毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计 &…

7.C++:多态

一、 virtual关键字 //1.可以修饰原函数&#xff0c;为了完成虚函数的重写&#xff0c;满足多态的条件之一&#xff1b; //2.可以在菱形继承中&#xff0c;完成虚继承&#xff0c;解决数据冗余和二义性&#xff1b; 两个地方使用同一关键字&#xff0c;但二者间没有一点关联 二…

鸿蒙入门04-真机运行“遥遥领先”

如果你有一台真的 "遥遥领先"那么是可以直接在手机上真机运行你的项目的我们也来尝试一下运行 一、手机设置开发者模式 打开手机设置 打开手机设置界面 向下滑动到关于手机位置 快速连续点击版本号位置 下图所示位置快速连续点击 打开 3 - 5 次即可 会提示您已经进…

Jackson 2.x 系列【25】Spring Boot 集成之起步依赖、自动配置

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 本系列Jackson 版本 2.17.0 本系列Spring Boot 版本 3.2.4 源码地址&#xff1a;https://gitee.com/pearl-organization/study-jaskson-demo 文章目录 1. 前言2. 起步依赖3. 自动配置3.1 JacksonPrope…

负载均衡集群——HAProxy

目录 1 HAProxy介绍 2 功能简介 3 实验组网介绍 4 实验步骤 4.1 通过 HAProxy 实现简单负载均衡调度功能 步骤 1 安装 HAProxy 步骤 2 修改配置 HAProxy 文件 4.2 HAProxy 监控页面配置 步骤 1 修改 HAProxy 配置文件 步骤 2 查看监控页面 3.3 HAProxy 日志相关配置 …

超详细!Python中 pip 常用命令

相信对于大多数熟悉Python的人来说&#xff0c;一定都听说并且使用过pip这个工具&#xff0c;但是对它的了解可能还不一定是非常的透彻&#xff0c;今天小编就来为大家介绍10个使用pip的小技巧&#xff0c;相信对大家以后管理和使用Python当中的标准库会有帮助。 安装 当然在…

论文解读:FREE LUNCH FOR FEW-SHOT LEARNING: DISTRIBUTION CALIBRATION

文章汇总 问题 学习到的模型很容易因为只有少数训练样本形成的有偏分布而变得过拟合。 动机 我们假设特征表示中的每个维度都遵循高斯分布&#xff0c;因此分布的均值和方差可以借鉴类似类的均值和方差&#xff0c;这些类的统计量可以通过足够数量的样本得到更好的估计。 …

PHP反序列化命令执行+PHP反序列化POP大链 +PHP反序列化基础

[题目信息]&#xff1a; 题目名称题目难度PHP反序列化命令执行1 [题目考点]&#xff1a; 反序列化命令执行&#xff0c;获取题目flag。[Flag格式]: SangFor{t5euvZ_OB8Jd_h2-}[环境部署]&#xff1a; docker-compose.yml文件或者docker tar原始文件。 docker-compose up …

ArcGIS三维景观分层显示

今天将向大家介绍的事在ArcGIS中如何创建多层三维显示。 地表为影像的 地表为地形晕渲的 在土壤分层、油气分层等都有着十分重要的应用。下面我们具体来看看实现过程 一、 准备数据及提取栅格范围 我们这次准备的数据是之前GIS100例-30讲的案例数据。《ArcGIS三维影像图剖面图…

【网站项目】学习资料销售平台 小程序

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

用c++写一个代码解析器需要向哪方面学习?

我以前在中小游戏公司工作的时候&#xff0c;其中一项比较琐碎的工作就是为游戏项目建库建表&#xff0c;主要是为了做数据分析。作为一个职能部门的打杂PHP&#xff0c;对游戏业务并没有什么发言权&#xff0c;但是每次建库建表&#xff0c;却是苦不堪言。 同时部门的基础设施…

EPP和EDR是什么,如何提高端点安全性

端点保护平台&#xff08;EPP&#xff09;和端点检测和响应&#xff08;EDR&#xff09;工具是两种常用于保护端点系统免受威胁的安全产品。EPP 是一种全面的安全解决方案&#xff0c;提供一系列功能来检测和防止对端点设备的威胁。同时&#xff0c;EDR专门用于实时监控、检测和…

CC254X 8051芯片手册介绍

1 8051CPU 8051是一种8位元的单芯片微控制器&#xff0c;属于MCS-51单芯片的一种&#xff0c;由英特尔(Intel)公司于1981年制造。Intel公司将MCS51的核心技术授权给了很多其它公司&#xff0c;所以有很多公司在做以8051为核心的单片机&#xff0c;如Atmel、飞利浦、深联华等公…

AI讲师大模型培训老师叶梓:大模型应用的方向探讨

大模型应用的关键方向及其落地案例可以从多个角度进行探讨&#xff0c;结合最新的研究和实际应用案例&#xff0c;我们可以更全面地理解这些技术如何推动社会和经济的发展。 Agent&#xff08;数字代理&#xff09;: 方向说明:Agent方向的AI技术旨在创建能够独立执行任务、做出…