服务器资源与角色
| 身份 | 角色 | ip | 版本 |
|---|---|---|---|
| 服务器 | Gitlab | 10.0.0.133 | Rocky Linux 9 |
| 服务器 | Jenkins | 10.0.0.134 | Rocky Linux 9 |
| 服务器 | Web | 10.0.0.135 | Rocky Linux 9 |
| 服务器 | APP | 10.0.0.137 | Rocky Linux 9 |
| 服务器 | Database | 10.0.0.138 | Rocky Linux 9 |
| 服务器 | Harbor | 10.0.0.139 | Rocky Linux 9 |
| 中间件 | Harbor | - | 2.14.2 |
基于
若依分离版(ruoyi-vue)项目的发布
传统java项目因为前后端代码耦合度高,修改某处需要整体重新打包,复用性和可维护性较低。因代码的物理耦合,导致部署时候需要部署在同一服务器,对服务器资源要求较高,服务器宕机对业务的影响巨大。
因此,前后端分离是目前主流的 Web 项目架构模式,是将代码解耦后将前后端拆分成独立应用,前端只需加载静态界面,用户请求、业务处理通过后端完成,前后端只需要通过API通信。这就意味着在部署上前后端可以部署在不同服务器甚至集群,只需满足服务器基础通信就行。
之前
02-静态页面的发布就是前端的部署方式,只是目前都是通过nodejs将前端构建打包成dist目录交给nginx代理;而03-Maven项目的发布就是后端的部署方式,也是通过maven将后端打包构建成jar包后使用java -jar启动通过Jenkins一键发布前后端分离项目,其实就是通过一个任务同时完成前、后端的打包、发送、启动。因此目前的完整步骤是:
Jenkins拉取代码-->进入前端目录构建前端-->进入后端目录构建后端-->分别发送前、后端构建产物到对应服务器-->前端服务器启动nginx代理-->后端服务器java -jar启动-->浏览器成功访问,业务请求处理正常
基于服务器的发布
一、源码准备
1.Ruoyi-Vue介绍
RuoYi-Vue是一个 Java EE 企业级快速开发平台,基于经典技术组合(Spring Boot、Spring Security、MyBatis、Jwt、Vue),内置模块如:部门管理、角色用户、菜单及按钮授权、数据权限、系统参数、日志管理、通知公告、代码生成等。在线定时任务配置,支持集群,支持多数据源,支持分布式事务等。
若依官网:http://ruoyi.vip
演示地址:http://vue.ruoyi.vip
代码下载:https://gitee.com/y_project/RuoYi-Vue
2.复制官方代码仓库
首先将ruoyi-vue拉取到Gitlab仓库
创建Gitlab空白仓库
Ruoyi-Vue:拉取gitee公有项目RuoYi-Vue到Gitlab服务器本地
推送已拉取到本地的项目到创建好的Gitlab私有仓库
# 镜像克隆Gitee仓库 git clone --mirror https://gitee.com/y_project/RuoYi-Vue.git ruoyi-vue-mirror.git cd ruoyi-vue-mirror.git # 替换远程仓库的推送地址为私有GitLab仓库 git remote set-url --push origin http://localhost:8765/root/Ruoyi-Vue.git # 推送到私有仓库 git push --mirror - 输入Gitlab的账号和密码| 复制仓库 |
|---|
3.数据准备
ruoyi-vue需要mysql和redis提供数据存储交互
在
Database服务器先安装mysql和redis,后根据官方文档,创建对应数据库,导入sql脚本
# 清理环境 yum -y erase `rpm -qa | grep -E "mysql|mariadb"` rm -rf /etc/my* /var/lib/mysql* /var/log/mysql* # 安装mysql的官方YUM仓库与指定安装8.0版本 yum install -y https://dev.mysql.com/get/mysql84-community-release-el9-2.noarch.rpm yum install -y mysql-community-server --enablerepo mysql80-community --disablerepo mysql-8.4-lts-community # 启动mysql并修改初始密码 systemctl start mysqld # 查看版本验证安装 mysql --version mysql Ver 8.0.42 for Linux on x86_64 (MySQL Community Server - GPL) # 跳过密码登录 mysqld --skip-grant-tables --user=mysql & mysql -uroot # 修改所有root密码 mysql > ALTER USER 'root'@'localhost' IDENTIFIED BY 'Pangle@123'; mysql > ALTER USER 'root'@'%' IDENTIFIED BY 'Pangle@123'; mysql > FLUSH PRIVILEGES; # 重启mysql pkill -9 mysql systemctl restart mysqld # 进入mysql创建数据库 mysql -uroot -pPangle@123 mysql > create database `ry-vue`; # Database服务下载ruoyi-vue git clone https://gitee.com/y_project/RuoYi-Vue.git cd RuoYi-Vue/sql/ # 导入sql脚本数据 mysql -uroot -pPangle@123 -f ry-vue < ry_20250522.sql mysql -uroot -pPangle@123 -f ry-vue < quartz.sql # 下载redis yum install redis # 编辑配置文件,修改所有ip开放 vim /etc/redis/redis.conf ----------------------------------------------------------------------- bind 0.0.0.0 ----------------------------------------------------------------------- # 启动redis systemctl start redis4.通信要点
Web项目请求大致流程是:
前端接收用户请求-->将请求转发给后端-->后端处理请求-->读写数据库数据-->逐级返回数据,而因为前后端项目可部署在不同服务器上,要满足流程的成功,我们需要让前端、后端、数据库直接可以通信。通俗的说:告诉前端后端在哪里、告诉后端数据库在哪里因此,我们需要修改Gitlab中
Ruoyi-Vue的相关配置,让他们在发布到服务器后可以互相通信处理请求与数据
配置redis地址
打开
ruoyi-admin/src/main/resources/application.yml点击编辑-编辑单个文件,按以下修改后点击提交更改
~~~ data: # redis 配置 redis: # 地址:将localhost改为数据库服务器IP host: 10.0.0.138 # 端口,默认为6379 port: 6379 ~~~
配置mysql地址
打开
ruoyi-admin/src/main/resources/application-druid.yml点击编辑-编辑单个文件,按以下修改后点击提交更改
~~~ druid: # 主库数据源:将localhost改为数据库服务器IP,写入root用户密码 master: url: jdbc:mysql://10.0.0.138:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 username: root password: Pangle@123 ~~~
为前端配置后端地址
打开
ruoyi-ui/vue.config.js点击编辑-编辑单个文件,按以下修改后点击提交更改
const baseUrl = 'http://10.0.0.137:8080' // 后端接口:将localhost改为App服务器IP
完成以上配置,我们就准备好了Ruoyi-Vue项目在发布前的所有源码配置,后续只需要通过Jenkins对其进行自动化构建发布即可
二、Jenkins任务配置
1.新建任务,拉取代码
Jenkins主页点击
新建任务,任务名Ruoyi-Vue,选择自由风格项目确定源码管理选择Git,写入Ruoyi-Vue的Gitlab地址
因为我们是私有项目,这里会显示鉴权失败,因为私有项目的拉取需要账密或者令牌的验证
点击
添加Jenkins凭据,类型就用Username with password账号密码形式用户名:Gitlab的用户root
密码:root用户的密码
描述:在Jenkins中选择此账密的标识,可以写入
Gitlab私有仓库-账号-密码点击
添加,在Credentials选择刚配置的Gitlab私有仓库-账号-密码,然后就可以看到之前鉴权失败的报错消失点击应用后保存,先构建一次验证
拉取代码步骤配置成功
| 拉取代码 |
|---|
2.打包前端
在之前我们单个任务只需要对拉取到的后端代码用
maven构建成jar包,而Ruoyi-Vue的前端使用vue框架开发的,可以将其依赖的静态资源等通过nodejs打包成dist包所以在Jenkins任务的
构建步骤中,主要完成:nodejs打包前端成dist、maven构建后端成jar包
- 下载NodeJS
首先需要在
Jenkins服务器安装nodejs
# 下载并安装 nvm: curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash # 代替重启 shell \. "$HOME/.nvm/nvm.sh" # 下载并安装 Node.js: nvm install 24 # 验证 Node.js 版本: node -v # Should print "v24.14.0". # 验证 npm 版本: npm -v # Should print "11.9.0". # npm使用国内淘宝镜像 npm config set registry https://registry.npmmirror.com/- 配置全局工具
查找命令位置,Jenkins主页右上角
设置-->全局工具配置找到
NodeJS安装,点击新增NodeJS取消勾选自动安装
别名:Jenkins中此工具的标识,配置为
node&npm安装目录:之前查到的命令上层路径,配置为
/usr/bin应用后保存
# 服务器查看node、npm命令安装位置 which node npm /usr/bin/node /usr/bin/npm| 打包前端 |
|---|
- 打包前端包
任务
增加构建步骤,选择执行shell
进入前端目录
cd ruoyi-ui使用npm下载依赖
npm install --registry=https://registry.npmmirror.com根据依赖和源码打成dist包
npm run build:prod点击应用后保存,先构建验证
打包前端步骤配置成功
| 打包前端 |
|---|
- 优化打包命令
可以看到通过npm已将前端打包成dist目录,但因为之后我们需要将dist包整个发送到Web服务器,所以可以优化打包的命令
通过
zip命令将dist压缩为zip压缩包,小体积方便后续发送,并且通过BUILD_NUMBER环境变量命名压缩包,BUILD_NUMBER是Jenkins内置的环境变量,取值是该任务本次构建的构建号因为我们的Jenkins任务会多次运行,每次都会多一个zip压缩包,所以我们在构建之前先删除之前的压缩包
最终优化后命令为:
cd ruoyi-ui rm -rf dist*.zip npm install --registry=https://registry.npmmirror.com npm run build:prod zip -r dist-${BUILD_NUMBER}.zip ./dist/*3.构建后端
- 工具确认
之前的文档有通过maven构建jar包的过程,所以Jenkins服务器已有maven
若未按之前文档流程,这里需要像NodeJS一样安装maven后配置全局工具
- 构建后端
任务
增加构建步骤,选择执行shell
jar包的构建依赖pom.xml文件,Ruoyi-Vue的构建需要进入
ruoyi-admin目录,所以此处用shell命令进入目录cd ruoyi-admin任务
增加构建步骤,选择调用顶层 Maven 目标
Maven版本:选择配置好的全局工具
目标:此构建步骤本质是执行mvn命令,所以目标嵌入的就是mvn命令的选项和参数
clean package -DskipTests依旧应用后保存,立即构建验证配置
| 构建后端 |
|---|
4.运行前端
- 配置web服务器
在前端打包完成后,就需要将其推送到web服务器,这里我们使用Publish Over SSH插件,可以使用这个插件配置连接指定服务器,并执行相关命令、
在Jenkins
系统管理->插件管理中Available plugins搜索Publish Over SSH插件并安装在Jenkins
系统管理->系统设置中,拉到最下边可以看到该插件提供的相关设置,点击新增,添加web服务器相关信息
Name自定义,作为服务器在Jenkins中的标识
Hostname为目标服务器IP
Username为登录用户名
Remote Directory为登录目标服务器后的工作目录
/usr/local/Ruoyi-Vue,如果该目录不存在,则需要去目标服务器手动创建点击高级,勾选
Use password authentication, or use a different key,在Passphrase / Password填写登录用户名对应的密码
| 运行前端 |
|---|
- 发送前端包
任务
增加构建后操作步骤,选择Send build artifacts over SSH
在SSH Server中,
Name选择我们之前在系统设置中配置的目标服务器名称web
Transfer Set中Source files代表将Jenkins所在服务器那些文件复制到目标服务器,这里我们选择本次构建压缩好后的zip压缩包:ruoyi-ui/dist-${BUILD_NUMBER}.zip
Exec command为复制后需要在目标服务器执行的命令
首先进入目标目录
cd /usr/local/Ruoyi-Vue/ruoyi-ui,然后实现:a.解压zip压缩包
unzip -o dist-${BUILD_NUMBER}.zip;
b.删除压缩包rm -rf dist-${BUILD_NUMBER}.zip
| 运行前端 |
|---|
- 添加nginx配置文件
解压后dist目录是支持被nginx代理的,因为打包后会生成index,html主页文件
编辑配置文件:
vim /etc/nginx/conf.d/Ruoyi-Vue.conf插入以下数据,注意设置后端转发
然后
nginx -t检查无误后nginx -s reload平滑应用
server { listen 82; server_name localhost; charset utf-8; location / { root /usr/local/Ruoyi-Vue/ruoyi-ui/dist; try_files $uri $uri/ /index.html; index index.html index.htm; } location /prod-api/ { proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header REMOTE-HOST $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://10.0.0.137:8080/; } # springdoc proxy location ~ ^/v3/api-docs/(.*) { proxy_pass http://10.0.0.137:8080/v3/api-docs/$1; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } }- 访问测试
然后通过浏览器访问
10.0.0.135:82,可以看到若依的登录页,只不过此时不显示验证码、无法登录。此为前端发布成功
| 访问测试 |
|---|
5.运行后端
- 配置App服务器
根据
配置web服务器的步骤添加好App服务器此处创建并配置App服务器工作目录
/usr/local/Ruoyi-Vue
- 发送后端jar包
在任务配置中
Send build artifacts over SSH点击Add Server
在SSH Server中,
Name选择我们之前在系统设置中配置的目标服务器名称App
Transfer Set中Source files代表将Jenkins所在服务器那些文件复制到目标服务器,这里我们选择使用maven构建好的jar包:ruoyi-admin/target/ruoyi-admin.jar
Exec command为复制后需要在目标服务器执行的命令
首先进入目标目录
cd /usr/local/Ruoyi-Vue/ruoyi-admin/target然后使用nohup后台运行java -jar启动命令:
nohup java -jar ruoyi-admin.jar --server.address=0.0.0.0 > ruoyi.log 2>&1 &
| 运行后端 |
|---|
- 访问测试
再次通过浏览器访问
10.0.0.135:82,可以看到验证码正常显示,登录后功能正常使用admin/admin123
| 访问测试 |
|---|
基于Docker的发布
一、生产环境详解
在目前的公司项目中,预算是影响公司项目设计和服务架构的主要因素,因此大多数公司都是
采用前后端分离的项目设计,docker容器集群的生产架构。而微服务项目和大型k8s架构因为成本等因素大多数公司不会采用。因此,基于Docker发布前后端分离项目可以说算是行业主流,而因为前端目录在打包后只是一些静态资源且使用nginx代理指定路径,所以
前端大概率不会以容器方式运行,因为容器涉及到每次的dist目录映射、nginx配置文件的更新等。在此,我们学习通过Jenkins对前端和之前一样打包发布到服务器本地,后端通过docke运行成容器。因此,
前端的配置保留不变,只设计后端基于docker发布的步骤
二、后端配置
首先理清java项目运行成容器的流程:
通过Maven将项目构建成jar包
编写dockerfile,基于jdk基础镜像自定义镜像,作用是复制成品jar包到容器内,使用java -jar启动
Jenkins本地构建镜像,标准化命名镜像后上传到Harbor仓库
Jenkins通知App服务器前往Harbor仓库拉取指定镜像,然后运行成容器
1.新建任务、保留其他配置
像之前一样,创建新Jenkins自由风格任务
Ruoyi-Vue-Docker按
基于服务器的发布中二、1到二、4的配置保留其他配置
2.编写dockerfile
dockerfile的作用是通过配置自定义镜像,因为需要通过它本地构建,所以我们需要在
Gitlab的Ruoyi-Vue项目中创建docker目录并新建编辑dockerfile文件
# 镜像基于openjdk 17构建 FROM docker.io/openjdk:17 # 复制构建后的jar包到容器内指定目录 COPY ruoyi-admin.jar /usr/local/Ruoyi-Vue-Docker/ # 设置该容器工作目录 WORKDIR /usr/local/Ruoyi-Vue-Docker/ # 运行目录下的myapp.jar CMD java -jar ruoyi-admin.jar| 编写dockerfile |
|---|
3.Harbor创建仓库
我们首先可以点击主页新建项目,建立一个新的仓库,因截图时网络问题,Harbor服务器用的云服务器121.4.90.98*项目名称是这个仓库的名称,设置为ruoyi *访问级别如果未勾选公开则进入此仓库操作需要账号密码,设置勾选 *项目配额限制为此仓库空间占用限制,-1代表无限容量 *镜像代理暂时不需要设置
这个镜像仓库也像Gitlab一样,可以设置不同用户和角色进行合作管理
推送要求参考:07-Harbor镜像仓库-->二、2.推送要求
4.构建镜像、上传Harbor
任务
增加构建步骤,选择执行shell
dockerfile中有
COPY ruoyi-admin.jar /usr/local/Ruoyi-Vue-Docker/,需要复制当前目录下的ruoyi-admin.jar到容器内,而构建镜像时所在目录是dockerfile所在目录也就是docker/,因此,首先得将构建好的jar包复制到docker目录:mv ruoyi-admin/target/*.jar docker/根据dockerfile构建自定义镜像:
docker build -t ruoyi-vue:latest docker/登录Harbor仓库:
docker login -u admin -p Harbor12345 10.0.0.139:80,将镜像重命名成标准镜像名:docker tag ruoyi-vue:latest 10.0.0.139:80/ruoyi/ruoyi-vue:latest,之后推送Harbor仓库:docker push 10.0.0.139/ruoyi/ruoyi-vue:latest删除本地构建镜像:
docker rmi ruoyi-vue:latest依旧应用后保存,立即构建验证配置
| 上传Harbor |
|---|
5.App服务器制作运行脚本
在Jenkins完成镜像制作,推送镜像到Harbor仓库后,需要Jenkins通知目标App服务器,进入Harbor仓库拉取制作好的自定义镜像并将其运行成镜像
Jenkins告知App拉取哪个镜像
判断当前是否正在运行这个镜像形成的容器,需要停止并删除
判断当前是否存在当前镜像,需要删除
目标服务拉取Harbor上的镜像
将拉取下来的镜像运行成容器
而这些操作都让Jenkins来告知完成的话成本较大且每次修改都需要进入Jenkins的任务配置,我们可以在App服务器编写脚本完成这些操作,Jenkins服务器只需要让App运行这个脚本即可
并且在运行这个脚本时,标准镜像名中的每个参数都需要Jenkins服务器告知App服务器,App服务器才知道拉取哪个镜像。这些参数有
Harbor仓库地址、Harbor仓库名、镜像名、镜像版本其次容器运行时是需要占用App服务器的端口,Jenkins服务器也需要告知App服务器可占用的
端口号
# 在application服务器编辑脚本文件 vim /usr/bin/deploy.sh ------------------------------------------------------------------------------- harbor_addr=$1 harbor_repo=$2 project=$3 version=$4 host_port=$5 container_port=$6 # 由Jenkins告知需要拉取的镜像信息 imageName=$harbor_addr/$harbor_repo/$project:$version # step1:查看当前镜像是否有容器运行,若有则停止删除容器 containerID=`docker ps -a | grep ${project} | awk '{print $1}'` if [ "$containerID" != "" ] ; then docker stop $containerID docker rm $containerID fi # step2:查看当前是否存在相同镜像,如果有则删除 tag=`docker images --format "{{.Tag}}" ${project}` if [[ "$tag" =~ "$version" ]] ; then docker rmi $imageName fi # step3:登录远程Harbor仓库,拉取镜像 echo "Harbor12345" | docker login -u admin --password-stdin $harbor_addr docker pull $imageName # step4:将拉取的镜像运行成容器 docker run -d -p $host_port:$container_port --name $project $imageName -------------------------------------------------------------------------------6.构建后任务配置
在以上配置都完成后,我们只需要在Jenkins任务中让Jenkins通知目标服务器执行脚本即可
在任务配置中,已有构建后步骤为发送前端包,再点击
Add Server添加服务器
SSH Server的Name选择之前配置的App
Exec command写入执行目标服务器的脚本文件,并且传入所需参数sh /usr/bin/deploy.sh 10.0.0.139:80 mydevops ruoyi-vue latest 8080 8080
此处需要确保App服务器之前运行的进程未占用8080端口
应用保存后,点击构建查看控制台输出,无报错且App服务器容器运行正常,Ruoyi-Vue基于docker发布成功
| 构建任务 |
|---|
三、访问测试
通过浏览器访问
10.0.0.135:82,可以看到验证码正常显示,登录后功能正常使用admin/admin123
| 访问测试 |
|---|