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

基础镜像可选择:

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

在这里插入图片描述

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

services:demo:#  启动时传入镜像tag示例:BUILD_TAG=20240406-57 docker-compose up -dimage: registry.cn-guangzhou.aliyuncs.com/lyr-test/demo:${BUILD_TAG}container_name: demorestart: alwaysnetwork_mode: hostdeploy:resources:limits:cpus: '1.00'memory: 1Greservations:cpus: '0.10'memory: 256Menvironment:- 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 anyparameters {string(description: '代码分支', name: 'CODE_BRANCH_PARAM', defaultValue: 'master', trim: true)// 这在Jenkins的凭据里设置的待部署服务器的名称就是服务器的ip;用docker-compose部署一般只会部署几台服务器,如果量大,建议上k8sbooleanParam 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中创建的代码仓库密钥idCREDENTIALS_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/versionfree -mdf -hdocker -vgit -vmvn -vjava -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 pwdsh """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 -fdocker 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_1if (SERVER_1=="true") {server_list.add('10.0.24.8')}echo "SERVER_2:" + SERVER_2if (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_ipremote.user = "${SERVER_USER}"remote.password = "${SERVER_PWD}"remote.allowAnyHosts = truestage('远程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 -ddocker-compose ps"""echo "ssh部署脚本执行完成"}}}}}}}}}// 通知内容post {success {//成功通知echo "成功通知"}failure {// 失败通知echo "失败通知"}}
}

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

// 服务器集合
def server_list = []
// 所有的脚本命令放在pipeline中
pipeline {// 指定任务在哪个集群节点中执行,any表示任意节点agent anyparameters {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中创建的代码仓库密钥idCREDENTIALS_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/versionfree -mdf -hdocker -vgit -vmvn -vjava -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_1if (SERVER_1=="true") {server_list.add('10.0.24.8')}echo "SERVER_2:" + SERVER_2if (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_ipremote.user = "${SERVER_USER}"remote.password = "${SERVER_PWD}"remote.allowAnyHosts = truestage('远程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_1if (SERVER_1=="true") {server_list.add('10.0.24.8')}echo "SERVER_2:" + SERVER_2if (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_ipremote.user = "${SERVER_USER}"remote.password = "${SERVER_PWD}"remote.allowAnyHosts = truestage('远程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 -ddocker-compose ps"""echo "ssh部署脚本执行完成"}}}}}}}}}// 通知内容post {success {//成功通知echo "成功通知"}failure {// 失败通知echo "失败通知"}}
}

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

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

相关文章

李廉洋;4.14黄金原油最新资讯,下周一盘走势分析及策略。

现货黄金昨日一度创下2430美元/盎司的历史新高,但随后一路回调至2344美元附近,较历史高位回落近百美元。分析师表示这是因为投资者在被视为过度的价格反弹中获利了结并离场所致。金融机构MKS PAMP SA的金属策略主管Nicky Shiels表示:“随着大…

基于Docker构建CI/CD工具链(六)使用Apifox进行自动化测试

添加测试接口 在Spring Boot Demo项目里实现一个简单的用户管理系统的后端功能。具体需求如下: 实现了一个RESTful API,提供了以下两个接口 : POST请求 /users:用于创建新的用户。GET请求 /users:用于获取所有用户的列…

STC89C52学习笔记(十一)

STC89C52学习笔记(十一) 综述:本文讲述了直流电机以及PWM调速。 一、直流电机 1、特点 (1)直流电机能将电能转化位机械能。 (2)直流电机有两个电极,电极正接时,电机…

【核心完整复现】基于目标级联法的微网群多主体分布式优化调度

1 主要内容 之前发布了华电学报的复现程序《基于目标级联法的微网群多主体分布式优化调度》,具体链接为【防骗版】基于目标级联法的微网群多主体分布式优化调度,虽然对模型及结果进行了复现,但是部分模型细节和参数并没有完全实现&#xff0…

2024长三角快递物流高质量创新发展论坛

2024长三角快递物流供应链与技术装备展览会(杭州) 2024年7月8-10日 | 杭州国际博览中心 指导单位:浙江省邮政管理局 中国快递协会 主办单位:浙江省快递行业协会 联合主办:上海市快递协会 江苏省快递协会 安徽省快递…

ubuntu22下使用vscode调试redis7源码环境搭建

ubuntu22下使用vscode调试redis7源码环境搭建 ##vscode launch.json配置文件 {// 使用 IntelliSense 了解相关属性。 // 悬停以查看现有属性的描述。// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid830387"version": "0.2.0&…

【DL水记】循环神经网络RNN的前世今生,Transformer的崛起,Mamba模型

文章目录 RNN网络简介传统RNN网络结构RNN的分类 长-短期记忆网络 (LSTM)GRU网络横空出世的Transformer网络Self-AttentionVisionTransformer Mamba模型Reference: RNN网络简介 “当人类接触新事物时,他们不会从头开始思考。就像你在阅读这篇文章时,你会根…

目标检测笔记

目标检测笔记 one-stage和two-stage目标检测算法Two-Stage 目标检测算法One-Stage 目标检测算法既然Faster R-CNN使得候选区域生成和目标检测可以在同一个网络中端到端训练,为什么它还是属于Two-stage算法? 目标检测模型,训练中的正负样本是什…

根据ELK官网指引部署ELK- ECK-Elastic-​ Kibana​-Learn-ELK-(一)

**Attention: 1、You need open the ELK official website and step by step to deploy . 2、If you copy my command ,you must check them if it not match your environment . 一、official website Elastic documentation | Elastic Check there. 二、 ECK简介…

常用接口测试工具/免费api

一 接口编辑文档 常用的接口文档编写apipost 二 免费接口测试 api 1. thecat 含有: The Cat API - Cat as a Service The Cat API 2. public-apis 进入页面往下拉 三 常用接口测试工具 postman 四 常用接口性能测试工具 Jmeter,loadrunner

FRDM-MCXN947开发板之RGB灯

一、背景 RGB LED:通过红、绿、蓝三种颜色组合发光的LED,可以理解由三个不同发光属性的LED组成,这个是LCD平板显示原理的基础,一个LED相当于屏幕上面的一个像素 FRDM-MCXN947集成了一块RGB LED,它由三个GPIO口驱动&am…

2024 Guitar Pro 8.1.2-27 (x64) win/mac中文激活版破解版

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

Docker Image (镜像) 常见命令

Docker Image (镜像) 常用命令 docker images 功能:列出本地所有的镜像。如果镜像 ID 相同,但是 Tag 标签不同,也会被当作不同的条目被列出来。 语法: docker images [options] [REPOSITORY[:TAG]] 别名: docker ima…

如何对图像进行聚类

文章来源:https://medium.com/voxel51/how-to-cluster-images-6e09bdff7361 2024 年 4 月 10 日 使用 FiftyOne、Scikit-learn和特征嵌入 在 2024 年深度学习的计算密集型环境中,集群一词最常出现在讨论 GPU 集群时--高度优化的矩阵乘法机器的大规模集…

海洋信息管理系统:守护蓝色星球,促进海洋经济新发展

海洋,覆盖地球表面超过七成的广阔水域,是生命之源,也是经济发展的重要空间。然而,随着人类活动的增加,海洋生态环境面临严峻挑战,海洋资源的可持续利用成为全球关注的焦点。在这样的背景下,构建…

数字IC/FPGA——亚稳态及跨时钟域

什么是亚稳态亚稳态会造成什么平均故障间隔时间如何解决亚稳态同步时钟和异步时钟单bit电平信号如何跨时钟域单bit脉冲信号如何跨时钟域多bit信号如何跨时钟域 目录 一、亚稳态1.基本概念2.危害3.平均故障时间4.解决亚稳态的方法 二、跨时钟域1.同步电路和异步电路(…

RNN知识体系构筑:详尽阐述其理论基础、技术架构及其在处理序列数据挑战中的创新应用

一、为什么需要RNN 尽管神经网络被视为一种强大且理论上能够近似任何连续函数的模型,尤其当训练数据充足时,它们能够在输入空间中的某个点( x )映射到输出空间的特定值( y ),然而,这并不能完全解释为何在众多应用场景中&#xff…

牛客2024【牛客赛文X】春招冲刺ONT61 每日温度【hard 单调栈 Java、Go、PHP】

题目 题目链接: https://www.nowcoder.com/practice/1f54e163e6944cc7b8759cc09e9c78d8 思路 单调栈最直接的应用就是获取数组中每个位置i,i的左边第一个比i大或者小的位置/数以及,i的右边第一个比i大或者小的位置/数不懂的同学看这里https://blog.csdn.net/Borsl…

String类中常见面试题

1.string类属于基本类型吗? string类不是基本类型;它属于引用数据类型 2.操作字符串的类有哪些?有什么区别? 有三种:string,stringBuilder,stringBuffer 区别: String:不可变类,字符串一旦被创建就不能…

Unity打包出来的apk安装时提示应用程式与手机不兼容,无法安装应用程式

1、遇到的问题 * 2、解决办法 这是因为你在Unity中导出来的apk手机安装包是32位的,才导致上述问题发生,要解决这个办法,需要在Unity中导出64位的手机安装包。 32位跟64位的区别,以及如何区分打出来的手机安装包是否是32位或者是…