前言 在之前的文章DevOps实战 中我们使用Jenkins进行了项目的部署,现在我们再使用Jenkins将之前实现的langchan4j智能助手 部署到服务器,使其能从外网被访问。项目部署后的访问地址:http://139.155.229.99:5173/。
基础服务部署 需要部署Jenkins、gitea和registry,可以查看文章DevOps实战 -‘基础服务安装部署’;另外本服务还需要部署redis和milvus
部署redis 我这里依然采用docker-compose的方式部署,这里我直接贴出docker-compose.yml文件
1 2 3 4 5 6 7 8 9 10 11 12 13 # redis.conf protected-mode no port 6379 timeout 0 save 900 1  save 300 10 save 60 10000 rdbcompression yes dbfilename dump.rdb dir /data appendonly yes appendfsync everysec requirepass austin 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 services:   redis:      image:  redis:6.2.5      container_name:  redis      restart:  always      ports:        -  6379 :6379      volumes:        -  ./redis.conf:/usr/local/etc/redis/redis.conf:rw        -  ./data:/data:rw        -  ./logs:/logs      command:        /bin/bash  -c  "redis-server /usr/local/etc/redis/redis.conf"  
部署milvus milvus的docker-compose.yml文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 services:   etcd:      container_name:  milvus-etcd      image:  quay.io/coreos/etcd:v3.5.18      environment:        -  ETCD_AUTO_COMPACTION_MODE=revision        -  ETCD_AUTO_COMPACTION_RETENTION=1000        -  ETCD_QUOTA_BACKEND_BYTES=4294967296        -  ETCD_SNAPSHOT_COUNT=50000      volumes:        -  ${DOCKER_VOLUME_DIRECTORY:-.}/volumes/etcd:/etcd      command:  etcd  -advertise-client-urls=http://127.0.0.1:2379  -listen-client-urls  http://0.0.0.0:2379  --data-dir  /etcd      healthcheck:        test:  ["CMD" , "etcdctl" , "endpoint" , "health" ]       interval:  30s        timeout:  20s        retries:  3    minio:      container_name:  milvus-minio      image:  minio/minio:RELEASE.2023-03-20T20-16-18Z      environment:        MINIO_ACCESS_KEY:  minioadmin        MINIO_SECRET_KEY:  minioadmin      ports:        -  "9001:9001"        -  "9000:9000"      volumes:        -  ${DOCKER_VOLUME_DIRECTORY:-.}/volumes/minio:/minio_data      command:  minio  server  /minio_data  --console-address  ":9001"      healthcheck:        test:  ["CMD" , "curl" , "-f" , "http://localhost:9000/minio/health/live" ]       interval:  30s        timeout:  20s        retries:  3    standalone:      container_name:  milvus-standalone      image:  milvusdb/milvus:v2.5.6      command:  ["milvus" , "run" , "standalone" ]     security_opt:      -  seccomp:unconfined      environment:        ETCD_ENDPOINTS:  etcd:2379        MINIO_ADDRESS:  minio:9000      volumes:        -  ${DOCKER_VOLUME_DIRECTORY:-.}/volumes/milvus:/var/lib/milvus      healthcheck:        test:  ["CMD" , "curl" , "-f" , "http://localhost:9091/healthz" ]       interval:  30s        start_period:  90s        timeout:  20s        retries:  3      ports:        -  "19530:19530"        -  "9091:9091"      depends_on:        -  "etcd"        -  "minio"  networks:   default:      name:  milvus  
使用attu连接上milvus,创建名称为‘movies’新的collection,这里可以查看文章SpringAI打造私有知识库 中‘实现’-‘环境准备’-‘向量数据库Milvus’
部署langchain4j-demo项目 修改Jenkins中JDK、Maven的配置 我们在Jenkins中配置的也是jdk8,现在需要添加新的jdk21;maven当然也需要重新修改配置
添加JDK21 我们先将jdk21(linux版)解压到Jenkins的tool目录(Jenkins的docker-compose.yml文件中挂载的路径)
进入Jenkins页面‘系统管理’-‘全局工具管理’-‘JDK安装’-‘新增JDK’,填写刚才解压的路径
添加Maven 我们查看langchain4j-demo项目的代码,可以看到maven的版本是3.9.9
这次我们在Jenkins中就使用3.9.7的版本,当然,也必须是linux版的;我们将maven解压到Jenkins的tool目录下
进入Jenkins页面‘系统管理’-‘全局工具管理’-‘Maven安装’-‘新增Maven’,填写刚才解压的路径
打开Maven的配置文件setting.xml,修改本地仓库路径和镜像源
1 2 3 4 5 6 7 8 9 10 # 本地仓库 <localRepository > /tool/repo</localRepository > # 镜像源 <mirror > 	<id > aliyunmaven</id >  	<mirrorOf > *,!spring-milestones,!spring-snapshots</mirrorOf >  	<name > 阿里云公共仓库</name >  	<url > https://maven.aliyun.com/repository/public</url >  </mirror > 
这里需要说明的是,现在langchain4j的代码在快速迭代中,可能还没有同步到公共仓库中,这里我们排除spring-milestones和spring-snapshots仓库,否则会导致报错
创建新的虚拟机 这里我们重新创建一台虚拟机部署服务,当然也可以使用之前创建好的;虚拟机的镜像我们依然使用centos7,具体创建过程参考文章虚拟机的初始准备 ;我们使用docker镜像的方式部署服务,所以虚拟机中硬性要求安装的软件就是docker,当然网络需要通畅;
创建Dockerfile并上传到gitea服务器 我们首先在gitea创建一个新的仓库langchain4j-demo,然后将本地代码与其关联
1 git remote add gitea-remote http://ip:3030/lkd7736241/langchain4j-demo.git 
新创建一个代码分支用于部署
修改redis和milvus的地址为服务器的地址(当然可以使用nacos灵活配置)
创建用于构建docker镜像的文件Dockerfile
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 # 使用openjdk21的镜像 # 这里设置的是项目的运行环境,因为项目的jar包已经在Jenkins中构建完成,所以这里只需要jre FROM eclipse-temurin:21-jre # 项目参数 ENV PARAMS="--spring.profiles.active=deploy" # JVM容器参数 #ENV JAVA_OPTS="-XX:+UseContainerSupport" # 设置工作目录 WORKDIR /build # 将jar包复制到容器中 COPY ./langchain4j-demo-0.0.1-SNAPSHOT.jar ./langchain4j-demo.jar # 运行jar包 ENTRYPOINT ["sh","-c","java -jar $JAVA_OPTS langchain4j-demo.jar $PARAMS"] 
注:Dockerfile的目录与后文‘生成Jenkinsfile’-‘将Dockerfile推送到目标服务器’中的‘source files’路径应该一致 
 
将代码推送到gitea服务器(如果是第一次推送需要填写用户名和密码)
1 git push gitea-remote deploy 
当我们在gitea服务器看到推送的代码,这一步就完成了
创建目标服务器 我们在Jenkins中新建一个目标服务器,将刚才创建的虚拟机关联到Jenkins;进入Jenkins页面‘系统管理’-‘系统配置’-‘SSH Servers’,点击‘新增’,输入各项配置(‘Remote Directory’需要真实存在,如果没有需要到虚拟机中创建)
点击‘高级’,勾选‘Use password’,输入密码;输入端口号22
点击‘Test Configuartion’进行测试,看到success,则目标服务器创建成功
创建多分支流水线任务 创建多分支流水线任务‘langchai4j-demo’
填写分支源,进入多分支流水线任务页面,点击‘配置’-‘分支源’,填入代码库地址
生成Jenkinsfile 
注:这里对Jenkinsfile做一个说明
这个文件就是流水线的部署流程;这里我将其分为4个步骤:(1)拉取代码;(2)构建jar包;(3)推送jar到目标服务器;(4)推送Dockerfile到目标服务器,同时进行构建docker镜像、运行docker容器等;
第(1)和(2)步都是在Jenkins服务器内执行的,与目标服务器无关
Jenkins执行sshPublisher时有严格的顺序,先推送指定的文件,然后再执行命令;而且如果没有推送的文件,服务器会自动关闭链接,导致命令执行失败
推送镜像到镜像服务器需要在docker配置文件中配置镜像服务器地址或者申请SSL证书,可以参考之前的文章‘DevOps实战’ -‘基础服务安装部署’-‘registry服务安装部署’
 
进入‘流水线语法’-‘片段生成器’
拉取deploy分支代码 步骤示例(选择git,填写仓库URL和分支)
	语法片段
1 git branch:  'deploy' , url:  'http://139.155.229.99:3030/lkd7736241/langchain4j-demo.git'  
利用maven构建jar包 	执行命令
1 sh /tool/apache-maven-3.9.7/bin/mvn clean package -Dmaven.test.skip=true  
	步骤示例	
	语法片段
1 sh 'sh /tool/apache-maven-3.9.7/bin/mvn clean package -Dmaven.test.skip=true'  
将构建好的jar包推送到目标服务器 	步骤示例
选择sshPublisher,填写sourcefiles(要推送的文件)、remove prefix(要去除的前缀)、remote directory(目标文件夹,如果为空则推送到新建目标服务器时配置的目标文件夹中)
	语法片段
1 sshPublisher(publishers:  [sshPublisherDesc(configName:  'centos7-11-langchain4j-demo' , transfers:  [sshTransfer(cleanRemote:  false , excludes:  '' , execCommand:  '' , execTimeout:  120000 , flatten:  false , makeEmptyDirs:  false , noDefaultExcludes:  false , patternSeparator:  '[, ]+' , remoteDirectory:  '' , remoteDirectorySDF:  false , removePrefix:  'target' , sourceFiles:  'target/*.jar' )], usePromotionTimestamp:  false , useWorkspaceInPromotion:  false , verbose:  false )]) 
将csv文件推送到目标服务器 步骤示例
	语法片段
1 2 sshPublisher(publishers:  [sshPublisherDesc(configName:  'centos7-11-langchain4j-demo' , transfers:  [sshTransfer(cleanRemote:  false , excludes:  '' , execCommand:  '''  ''' , execTimeout:  120000 , flatten:  false , makeEmptyDirs:  false , noDefaultExcludes:  false , patternSeparator:  '[, ]+' , remoteDirectory:  '' , remoteDirectorySDF:  false , removePrefix:  'src/main/resources/movies/' , sourceFiles:  'src/main/resources/movies/*.csv' )], usePromotionTimestamp:  false , useWorkspaceInPromotion:  false , verbose:  false )])
将Dockerfile推送到目标服务器,构建镜像、推送镜像并运行容器 	需要执行的命令
1 2 3 4 5 6 7 8 9 10 11 12 13 docker stop langchain4j-demo || true  docker rm  -f langchain4j-demo || true  docker rmi -f qiuli/langchain4j-demo:1.0 || true  docker rmi -f 192.168.124.7:5000/qiuli/langchain4j-demo:1.0 || true  docker build -t qiuli/langchain4j-demo:1.0 /usr/local/project/langchain4j-demo docker run -d -p 8082:8082 --name=langchain4j-demo qiuli/langchain4j-demo:1.0 docker tag qiuli/langchain4j-demo:1.0 192.168.124.7:5000/qiuli/langchain4j-demo:1.0 docker push 192.168.124.7:5000/qiuli/langchain4j-demo:1.0 
	步骤示例
	语法片段
1 2 3 4 5 6 7 8 sshPublisher(publishers:  [sshPublisherDesc(configName:  'centos7-11-langchain4j-demo' , transfers:  [sshTransfer(cleanRemote:  false , excludes:  '' , execCommand:  '''docker stop langchain4j-demo || true  docker rm -f langchain4j-demo || true docker rmi -f qiuli/langchain4j-demo:1.0 || true docker rmi -f 192.168.124.7:5000/qiuli/langchain4j-demo:1.0 || true docker build -t qiuli/langchain4j-demo:1.0 /usr/local/project/langchain4j-demo docker run -d -p 8082:8082 --name=langchain4j-demo qiuli/langchain4j-demo:1.0 docker tag qiuli/langchain4j-demo:1.0 192.168.124.7:5000/qiuli/langchain4j-demo:1.0 docker push 192.168.124.7:5000/qiuli/langchain4j-demo:1.0''' , execTimeout:  120000 , flatten:  false , makeEmptyDirs:  false , noDefaultExcludes:  false , patternSeparator:  '[, ]+' , remoteDirectory:  '' , remoteDirectorySDF:  false , removePrefix:  'docker' , sourceFiles:  'docker/Dockerfile' )], usePromotionTimestamp:  false , useWorkspaceInPromotion:  false , verbose:  false )])
完整的Jenkinsfile文件 将各片段粘贴到Jenkinsfile文件的框架中,形成完整的文件,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 pipeline {     agent any 	tools  { 	     	    jdk "jdk-21"  	     	    maven "apache-maven-3.9.7"  	} 	     stages {         stage('拉取deploy分支代码' ) {             steps { 				git branch:  'deploy' , url:  'http://139.155.229.99:3030/lkd7736241/langchain4j-demo.git'  				echo '拉取成功'              }         } 		 		stage('执行构建' ) {             steps { 				sh 'sh /tool/apache-maven-3.9.7/bin/mvn clean package -Dmaven.test.skip=true'  				echo '构建完成'              }         }                  stage('将构建好的jar包推送到目标服务器' ) {             steps {                 sshPublisher(publishers:  [sshPublisherDesc(configName:  'centos7-11-langchain4j-demo' , transfers:  [sshTransfer(cleanRemote:  false , excludes:  '' , execCommand:  '''                  ''' , execTimeout:  120000 , flatten:  false , makeEmptyDirs:  false , noDefaultExcludes:  false , patternSeparator:  '[, ]+' , remoteDirectory:  '' , remoteDirectorySDF:  false , removePrefix:  'target' , sourceFiles:  'target/*jar' )], usePromotionTimestamp:  false , useWorkspaceInPromotion:  false , verbose:  false )])                echo '推送jar包完成'              }         }                  stage('将csv文件推送到目标服务器' ) {             steps {                 sshPublisher(publishers:  [sshPublisherDesc(configName:  'centos7-11-langchain4j-demo' , transfers:  [sshTransfer(cleanRemote:  false , excludes:  '' , execCommand:  '''  ''' , execTimeout:  120000 , flatten:  false , makeEmptyDirs:  false , noDefaultExcludes:  false , patternSeparator:  '[, ]+' , remoteDirectory:  '' , remoteDirectorySDF:  false , removePrefix:  'src/main/resources/movies/' , sourceFiles:  'src/main/resources/movies/*.csv' )], usePromotionTimestamp:  false , useWorkspaceInPromotion:  false , verbose:  false )])                echo '推送csv文件完成'              }         }                  stage('将Dockerfile推送到目标服务器,构建镜像、推送镜像并运行容器' ) {             steps {                 sshPublisher(publishers:  [sshPublisherDesc(configName:  'centos7-11-langchain4j-demo' , transfers:  [sshTransfer(cleanRemote:  false , excludes:  '' , execCommand:  '''docker stop langchain4j-demo || true  docker rm -f langchain4j-demo || true docker rmi -f qiuli/langchain4j-demo:1.0 || true docker rmi -f 192.168.124.7:5000/qiuli/langchain4j-demo:1.0 || true docker build -t qiuli/langchain4j-demo:1.0 /usr/local/project/langchain4j-demo docker run -d -p 8082:8082 --name=langchain4j-demo qiuli/langchain4j-demo:1.0 docker tag qiuli/langchain4j-demo:1.0 192.168.124.7:5000/qiuli/langchain4j-demo:1.0 docker push 192.168.124.7:5000/qiuli/langchain4j-demo:1.0''' , execTimeout:  120000 , flatten:  false , makeEmptyDirs:  false , noDefaultExcludes:  false , patternSeparator:  '[, ]+' , remoteDirectory:  '' , remoteDirectorySDF:  false , removePrefix:  'docker' , sourceFiles:  'docker/Dockerfile' )], usePromotionTimestamp:  false , useWorkspaceInPromotion:  false , verbose:  false )])                echo '部署完成'              }         }     } } 
提交Jenkinsfile并运行流水线 进入刚才创建的多分支流水线任务页面,点击‘配置’-‘Build Configuration’,设置Jenkinsfile的路径
可以看到,我们将Jenkinsfile的路径设置为根路径下的jenkins文件夹下,那么在项目中对应的地方创建目录和文件,将完整文件粘贴过去,再提交到代码服务器gitea;之后我们再来到流水线页面,点击‘立刻扫描 多分支流水线’;
当出现分支任务后,再点击‘打开BlueOcean’-‘分支’,再点击运行
可以看到流水线已经运行完毕,状态正常;我们在虚拟机中检查一下结果,首先看看docker中容器的运行情况
可以看到容器已经正常运行,再看看镜像的情况
可以看到镜像也正确的打了标签,我们再到镜像服务器看看镜像是否被正确推送
现在,流水线部署已经完成了
部署langchain4j-demo-front 手动部署 对于vue的项目,因为我的经验不是很多,先手动部署了一下;我还是使用docker来部署,不得不说容器化技术能避免不少问题,为我们节省不少时间
创建Dockerfile并上传到gitea服务器 在gitea服务器创建一个新的仓库langchain4j-demo-front,并与本地的代码关联
1 git remote add gitea-remote http://139.155.229.99:3030/lkd7736241/langchain4j-demo-front.git 
新创建一个代码分支用于部署
修改代码(如后端服务地址、服务的端口号)
注:这里需要说明的是,因为我们需要从外网访问,这里最后配置的是做了内网穿透后的云服务器IP和端口号(可以参考文章内网穿透教程 );如果没有这个需求,就配置后端服务的IP和端口号就行了,但是要记住我们的前端服务是使用docker部署的,因此IP不能配置127.0.0.1或者localhost,因为这样配置指向的是前端所在的docker容器本身 
 
创建用于构建docker镜像的文件Dockerfile
1 2 3 4 5 6 7 8 9 10 # 开发用单容器方案(使用 Node  镜像 + Vite  开发服务器) FROM  node :22.11 .0 -alpineWORKDIR  /appCOPY  package.json  package-lock.json  ./RUN  npm ciCOPY  . .EXPOSE  5173 CMD  ["npm" , "run" , "dev" ]
修改vite.config.js文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import  { defineConfig } from  'vite' import  vue from  '@vitejs/plugin-vue' export  default  defineConfig ({  plugins : [vue ()],   server : {     host : '0.0.0.0' ,       port : 5173    },   build : {     outDir : 'dist' ,     rollupOptions : {       input : '/src/main.js'        }   },   base : '/'    }) 
将代码推送到gitea服务器(如果是第一次推送需要填写用户名和密码)
1 git push gitea-remote deploy 
在gitea服务器看到代码已经成功提交
创建目录 在虚拟机的上创建项目目录,我创建的是/usr/local/project/langchain4j-demo-front
拉取代码 在上级目录执行命令
1 git clone  http://139.155.229.99:3030/lkd7736241/langchain4j-demo-front.git 
切换到deploy分支
拉取最新代码
构建docker镜像并运行容器 清理旧的镜像和容器
1 2 3 4 docker stop langchain4j-demo-front || true  docker rm  -f langchain4j-demo-front || true  docker rmi -f qiuli/langchain4j-demo-front:1.0 || true  docker rmi -f 192.168.124.7:5000/qiuli/langchain4j-demo-front:1.0 || true  
构建docker镜像
1 docker build -t qiuli/langchain4j-demo-front:1.0 /usr/local/project/langchain4j-demo-front 
运行新容器
1 docker run -d -p 5173:5173 --name=langchain4j-demo-front qiuli/langchain4j-demo-front:1.0 
为镜像制作标签
1 docker tag qiuli/langchain4j-demo-front:1.0 192.168.124.7:5000/qiuli/langchain4j-demo-front:1.0 
推送镜像到镜像服务器
1 docker push 192.168.124.7:5000/qiuli/langchain4j-demo-front:1.0 
验证部署结果 在宿主机的浏览器访问刚才部署的前端项目,已经能够成功访问
让我们来进行一下测试
如果配置了内网穿透,我们再从外网访问一下
Jenkins部署 创建Dockerfile并上传到gitea服务器 见‘手动部署’-‘创建Dockerfile并上传到gitea服务器’
创建新的目标服务器 在Jenkins中新建一个目标服务器,将刚才创建的虚拟机关联到Jenkins;进入Jenkins页面‘系统管理’-‘系统配置’-‘SSH Servers’,点击‘新增’,输入各项配置(‘Remote Directory’需要真实存在,如果没有需要到虚拟机中创建,这次我们的目标文件夹为‘/usr/local/project/langchain4j-demo-front’)
点击‘高级’,勾选‘Use password’,输入密码;输入端口号22
点击‘Test Configuartion’进行测试,看到success,则目标服务器创建成功
创建多分支流水线任务 创建多分支流水线任务‘langchain4j-demo-front’
填写分支源,点击‘配置’-‘分支源’,填入代码库地址
生成Jenkinsfile 拉取deploy分支代码 流水线语法片段
1 git branch: 'deploy' , url: 'http://139.155.229.99:3030/lkd7736241/langchain4j-demo-front.git'  
将代码复制到目标服务器并执行部署 步骤示例
需要执行的命令
1 2 3 4 5 6 7 8 9 10 11 12 13 docker stop langchain4j-demo-front || true  docker rm  -f langchain4j-demo-front || true  docker rmi -f qiuli/langchain4j-demo-front:1.0 || true  docker rmi -f 192.168.124.7:5000/qiuli/langchain4j-demo-front:1.0 || true  docker build -t qiuli/langchain4j-demo-front:1.0 /usr/local/project/langchain4j-demo-front docker run -d -p 5173:5173 --name=langchain4j-demo-front qiuli/langchain4j-demo-front:1.0 docker tag qiuli/langchain4j-demo-front:1.0 192.168.124.7:5000/qiuli/langchain4j-demo-front:1.0 docker push 192.168.124.7:5000/qiuli/langchain4j-demo-front:1.0 
流水线语法片段
1 2 3 4 5 6 7 8 sshPublisher(publishers:  [sshPublisherDesc(configName:  'centos7-11-langchain4j-demo-front' , transfers:  [sshTransfer(cleanRemote:  false , excludes:  '' , execCommand:  '''docker stop langchain4j-demo-front || true  docker rm -f langchain4j-demo-front || true docker rmi -f qiuli/langchain4j-demo-front:1.0 || true docker rmi -f 192.168.124.7:5000/qiuli/langchain4j-demo-front:1.0 || true docker build -t qiuli/langchain4j-demo-front:1.0 /usr/local/project/langchain4j-demo-front docker run -d -p 5173:5173 --name=langchain4j-demo-front qiuli/langchain4j-demo-front:1.0 docker tag qiuli/langchain4j-demo-front:1.0 192.168.124.7:5000/qiuli/langchain4j-demo-front:1.0 docker push 192.168.124.7:5000/qiuli/langchain4j-demo-front:1.0''' , execTimeout:  120000 , flatten:  false , makeEmptyDirs:  false , noDefaultExcludes:  false , patternSeparator:  '[, ]+' , remoteDirectory:  '' , remoteDirectorySDF:  false , removePrefix:  '' , sourceFiles:  '**/*' )], usePromotionTimestamp:  false , useWorkspaceInPromotion:  false , verbose:  false )])
完整的Jenkinsfile文件 将各片段粘贴到Jenkinsfile文件的框架中,形成完整的文件,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 pipeline {     agent any 	     stages {         stage('拉取deploy分支代码' ) {             steps { 				git branch:  'deploy' , url:  'http://139.155.229.99:3030/lkd7736241/langchain4j-demo-front.git'  				echo '拉取成功'              }         } 		 		stage('执行部署' ) {             steps { 				sshPublisher(publishers:  [sshPublisherDesc(configName:  'centos7-11-langchain4j-demo-front' , transfers:  [sshTransfer(cleanRemote:  false , excludes:  '' , execCommand:  '''docker stop langchain4j-demo-front || true  docker rm -f langchain4j-demo-front || true docker rmi -f qiuli/langchain4j-demo-front:1.0 || true docker rmi -f 192.168.124.7:5000/qiuli/langchain4j-demo-front:1.0 || true docker build -t qiuli/langchain4j-demo-front:1.0 /usr/local/project/langchain4j-demo-front docker run -d -p 5173:5173 --name=langchain4j-demo-front qiuli/langchain4j-demo-front:1.0 docker tag qiuli/langchain4j-demo-front:1.0 192.168.124.7:5000/qiuli/langchain4j-demo-front:1.0 docker push 192.168.124.7:5000/qiuli/langchain4j-demo-front:1.0''' , execTimeout:  120000 , flatten:  false , makeEmptyDirs:  false , noDefaultExcludes:  false , patternSeparator:  '[, ]+' , remoteDirectory:  '' , remoteDirectorySDF:  false , removePrefix:  '' , sourceFiles:  '**/*' )], usePromotionTimestamp:  false , useWorkspaceInPromotion:  false , verbose:  false )])				echo '部署完成'              }         }     } } 
提交Jenkinsfile并运行流水线 进入刚才创建的多分支流水线任务页面,点击‘配置’-‘Build Configuration’,设置Jenkinsfile的路径
在项目代码中创建Jenkinsfile,并提交到gitea代码服务器
进入Jenkins的流水线任务页面,点击‘立刻扫描 多分支流水线’;
当出现分支任务后,再点击‘打开BlueOcean’-‘分支’,再点击运行
验证部署结果 见前文‘手动部署’-‘验证部署结果’