前言 在之前的文章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’-‘分支’,再点击运行
验证部署结果 见前文‘手动部署’-‘验证部署结果’