ruoyi-vue部署篇
# ruoyi-vue 部署篇
# 官方文档
# 后端部署
# 部署步骤
# 脚本部署
- 使用 ry.sh 脚本部署
- 将项目打包成 ruoyi-admin.jar 文件
- 把 ruoyi-admin.jar 和 ry.sh 脚本上传到服务器同一目录下
- 给 ry.sh 脚本添加执行权限:
chmod +x ry.sh
1
使用以下命令控制服务:
./ry.sh start # 启动服务
./ry.sh stop # 停止服务
./ry.sh restart # 重启服务
./ry.sh status # 查看服务状态
1
2
3
4
2
3
4
# 手动部署
- 将 ruoyi-admin.jar 上传到服务器
- 在服务器上运行命令启动服务(日志输出路径自定义):
# 日志输出路径可自定义文件名
nohup java -Duser.timezone=Asia/Shanghai -Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m -jar ruoyi-admin.jar > ruoyi.log 2>&1 &
# 因为代码中有配置 logback.xml 文件,所以这里可指定日志输出路径为 /dev/null,这是一个特殊的“黑洞”设备文件,任何写入它的内容都会被丢弃。
nohup java -Duser.timezone=Asia/Shanghai -Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m -jar ruoyi-admin.jar > /dev/null 2>&1 &
1
2
3
4
5
2
3
4
5
指令分析:
>是标准输出(stdout)重定向操作符。logback.xml控制的是 Java 应用内部的日志输出(如Logger.info()、Logger.error()等);- 而 Shell 的
> file.log 2>&1控制的是整个 Java 进程的【标准输出(stdout)】和【标准错误(stderr)】。
/dev/null是一个特殊的“黑洞”设备文件,任何写入它的内容都会被丢弃。2>&1的意思是:把标准错误输出重定向到标准输出的位置。- 所以,
> /dev/null 2>&1表示 既不输出正常日志,也不输出错误日志(全部丢弃)
- 所以,
&表示 将进程放到后台运行。- ⚠️ 仅靠
&无法防止终端关闭时进程被杀,必须配合nohup或使用screen/tmux/systemd等工具。
- ⚠️ 仅靠
指令作用解释:
- 使用
nohup启动 Java 应用,使其忽略 hangup(SIGHUP)信号(即终端关闭不会杀死它); - 所有正常输出(stdout)和错误输出(stderr)都被丢弃,不写入任何日志文件;
- 进程在后台运行,命令执行后立即返回 shell 提示符。
# 确认 jar 包是否启动成功
有以下几种方法:
使用脚本查看状态
./ry.sh status
手动检查进程
ps -ef | grep ruoyi-admin.jar查单个ps -ef | grep java查全部
检查端口占用
netstat -tlnp | grep 8080
查看日志文件
访问健康检查接口
curl http://localhost:8080/actuator/health
测试业务接口
- 生成验证码接口:
curl -X GET --url "http://localhost:8080/captchaImage"
- 生成验证码接口:
# 脚本文件
# 配置优化
优化后的脚本
- 支持自定义环境启动,默认根据代码设置的配置来启动
#!/bin/sh
# ./ry.sh start 启动 stop 停止 restart 重启 status 状态
# ./ry.sh start prod 自定义生产环境启动
AppName=ruoyi-admin.jar
# JVM参数
JVM_OPTS="-Dname=$AppName -Duser.timezone=Asia/Shanghai -Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:NewRatio=1 -XX:SurvivorRatio=30 -XX:+UseParallelGC -XX:+UseParallelOldGC"
APP_HOME=`pwd`
LOG_PATH=$APP_HOME/logs/$AppName.log
# 获取操作名和环境参数
ACTION=$1
PROFILE=$2
if [ "$ACTION" = "" ];
then
echo -e "\033[0;31m 未输入操作名 \033[0m \033[0;34m {start|stop|restart|status} \033[0m"
exit 1
fi
if [ "$AppName" = "" ];
then
echo -e "\033[0;31m 未输入应用名 \033[0m"
exit 1
fi
function start()
{
PID=`ps -ef |grep java|grep $AppName|grep -v grep|awk '{print $2}'`
if [ x"$PID" != x"" ]; then
echo "$AppName is running..."
else
if [ "$PROFILE" != "" ]; then
nohup java $JVM_OPTS -jar $AppName --spring.profiles.active=$PROFILE > /dev/null 2>&1 &
else
nohup java $JVM_OPTS -jar $AppName > /dev/null 2>&1 &
fi
echo "Start $AppName with profile [$PROFILE] success..."
fi
}
function stop()
{
echo "Stop $AppName"
PID=""
query(){
PID=`ps -ef |grep java|grep $AppName|grep -v grep|awk '{print $2}'`
}
query
if [ x"$PID" != x"" ]; then
kill -TERM $PID
echo "$AppName (pid:$PID) exiting..."
while [ x"$PID" != x"" ]
do
sleep 1
query
done
echo "$AppName exited."
else
echo "$AppName already stopped."
fi
}
function restart()
{
stop
sleep 2
start
}
function status()
{
PID=`ps -ef |grep java|grep $AppName|grep -v grep|wc -l`
if [ $PID != 0 ];then
echo "$AppName is running..."
else
echo "$AppName is not running..."
fi
}
case $ACTION in
start)
start;;
stop)
stop;;
restart)
restart;;
status)
status;;
*)
echo -e "\033[0;31m 无效的操作名 \033[0m \033[0;34m {start|stop|restart|status} \033[0m"
exit 1;;
esac
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# 编码格式问题
将 Windows 下编辑或生成的 ry.sh 脚本直接复制到 Linux 服务器后,换行符和编码格式不兼容会导致脚本无法正常执行。
主要问题通常有两个
- 换行符不同(最常见)
- Windows 使用
CRLF(\r\n) - Linux 使用
LF(\n) - 在 Linux 中运行含
\r的脚本会报错
- Windows 使用
- 文件编码问题(较少见但可能)
- 如果文件保存为 UTF-8 with BOM 或 GBK,在某些 Linux 环境下可能解析异常。
解决方案
1、方法一:在 Linux 上用 dos2unix 转换(推荐)
- 安装
dos2unix(如未安装):
# CentOS / RHEL
sudo yum install -y dos2unix
# Ubuntu / Debian
sudo apt-get install -y dos2unix
1
2
3
4
5
2
3
4
5
- 转换脚本文件:
dos2unix ry.sh
1
- 添加执行权限并运行:
chmod +x ry.sh
./ry.sh
1
2
2
2、方法二:用 sed 手动删除 \r(无需安装工具)
- 原理:
sed删除每行末尾的回车符\r(即 Windows 的 CR)。
sed -i 's/\r$//' ry.sh
chmod +x ry.sh
./ry.sh
1
2
3
2
3
3、方法三:重新写脚本文件
# 编写新的脚本文件
vim ry-new.sh
# 将脚本内容复制进去
# 输入 :wq 指令,保存并退出
1
2
3
4
5
6
2
3
4
5
6
# 日志文件生成
- 官方脚本方式启动,只是定义了日志文件存放路径,默认是没有输入到对于的日志文件中的。
- 实际的文件存储位置,参考项目代码中的
logback.xml文件
<!-- 日志存放路径 -->
<property name="log.path" value="/home/ruoyi/logs" />
1
2
2
# 前端部署
部署 RuoYi-Vue 前端(即 ruoyi-ui)到生产环境,通常需要以下步骤:构建 → 配置 Nginx → 开放端口 → 启动服务验证。
# 本地构建前端
# 1. 克隆或获取 ruoyi-ui 源码
git clone https://gitee.com/y_project/RuoYi-Vue.git
cd RuoYi-Vue/ruoyi-ui
# 2. 安装依赖
npm install
# 或
yarn install
# 3. 修改后端 API 地址(关键!)
# 修改 .env.production 文件
# 这表示:所有 API 请求会发往 http://你的域名/prod-api/xxx
# 所以 Nginx 需要把 /prod-api 反向代理到后端!路径可自定义修改配置
VUE_APP_BASE_API = '/prod-api'
# 构建生产包,输出目录:dist/(里面是纯静态文件:HTML、JS、CSS)
npm run build:prod
# 或
yarn build:prod
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 将 dist 上传到服务器
例如上传到:/home/ruoyi/projects/ruoyi-ui
# 在服务器上创建目录
mkdir -p /home/ruoyi/projects/ruoyi-ui
# 本地用 scp 上传(示例)
scp -r dist/* user@192.168.2.128:/home/ruoyi/projects/ruoyi-ui
# 可以ssh工具上传
1
2
3
4
5
6
2
3
4
5
6
# 配置 Nginx 静态服务和 API 地址代理
参考下一章节...
# nginx 配置
# 整体结构说明
Nginx 配置分为三层:
nginx.conf
├── 全局块(worker_processes)
├── events 块(连接数)
└── http 块(核心:包含 MIME 类型、server 等)
└── server 块(一个虚拟主机,对应一个网站)
├── location / → 托管前端页面
├── location /prod-api/ → 代理后端接口
└── location ~ ^/v3... → 代理 Swagger 文档
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 如何查看 Nginx 实际加载了哪些配置?
# 查看主配置路径
nginx -V 2>&1 | grep -o 'conf-path=[^ ]*' # 通常输出 conf-path=/etc/nginx/nginx.conf
# 查看完整加载内容(调试用)
nginx -T
# 查看 nginx 是否还在运行
ps aux | grep nginx
# 查看端口是否监听
ss -tuln | grep :8072 # 替换成你的端口
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 重载 Nginx
- 编辑配置之后,需要执行重载指令才可生效
vim nginx.conf # 编辑配置
# 如果 nginx 在 PATH 中
nginx -s reload # 重载配置(不停机)
# 如果是自定义安装(如 /opt/nginx),并且 nginx -s reload 找不到指令
# 可以进入 sbin 目录执行
./nginx -s reload
# 或
/opt/nginx/sbin/nginx -s reload
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 开放防火墙端口(如 80)
# firewalld(CentOS/RHEL)
firewall-cmd --permanent --add-port=80/tcp
firewall-cmd --reload
# ufw(Ubuntu)
ufw allow 80/tcp
1
2
3
4
5
6
2
3
4
5
6
# ruoyi 官方配置解析
- 添加 ssl 证书配置,可改成 https 访问
# ================================
# 全局配置块(影响整个 Nginx 进程)
# ================================
# 指定 Nginx 启动的工作进程数量。
# 通常设置为 CPU 核心数(如 2、4),小型项目设为 1 即可。
worker_processes 1;
# ================================
# events 块:处理网络连接相关配置
# ================================
events {
# 每个工作进程允许的最大并发连接数。
# 默认 1024 足够中小型应用;高并发场景可调大(需配合系统 ulimit 设置)。
worker_connections 1024;
}
# ================================
# http 块:HTTP 协议通用配置(包含多个 server)
# ================================
http {
# 引入 MIME 类型映射文件(如 .js → application/javascript)
# 文件路径通常是 /etc/nginx/mime.types
include mime.types;
# 对于未识别的文件类型,默认按二进制流处理(避免浏览器误解析)
default_type application/octet-stream;
# 启用高效文件传输模式(利用内核 sendfile 系统调用,减少用户态/内核态拷贝)
sendfile on;
# 客户端与 Nginx 之间的 keep-alive 超时时间(秒)
# 保持连接可减少 TCP 握手开销,提升性能
keepalive_timeout 65;
# ================================
# server 块:定义一个虚拟主机(即一个网站)
# ================================
server {
# 监听 80 端口(HTTP 默认端口)
# 若需 HTTPS,则需监听 443 并配置 SSL 证书
listen 80;
# 服务器名称(域名)
# - "localhost":仅本机访问或通过 IP 访问时匹配
# - 实际部署建议改为你的公网域名(如 ruoyi.example.com)
# - 若无域名,可保留 localhost 或使用 "_"(通配任意域名)
server_name localhost;
# 设置响应头中的字符编码为 UTF-8,防止中文乱码
charset utf-8;
# -------------------------------------------------
# location / :处理所有前端页面请求(Vue SPA)
# -------------------------------------------------
location / {
# 指定静态资源根目录。
# 注意:此处应为前端打包后 dist 目录的父路径!
# 例如:若 index.html 路径是 /home/ruoyi/projects/ruoyi-ui/index.html,
# 则 root 必须设为此路径。
root /home/ruoyi/projects/ruoyi-ui;
# Vue Router 使用 history 模式时的核心配置:
# 尝试按顺序查找:
# 1. $uri → 精确匹配请求路径(如 /login)
# 2. $uri/ → 当作目录(如 /static/)
# 3. /index.html → 回退到首页(由 Vue Router 接管路由)
# 避免刷新页面出现 404
try_files $uri $uri/ /index.html;
# 默认首页文件(当访问目录时自动加载)
index index.html index.htm;
}
# -------------------------------------------------
# location /prod-api/ :代理所有后端 API 请求
# -------------------------------------------------
location /prod-api/ {
# 透传原始 Host 头(某些后端框架依赖此字段)
proxy_set_header Host $http_host;
# 传递客户端真实 IP 给后端(否则后端看到的是 127.0.0.1)
proxy_set_header X-Real-IP $remote_addr;
# 自定义头,记录客户端 IP(部分应用会读取此头)
proxy_set_header REMOTE-HOST $remote_addr;
# 传递完整的 X-Forwarded-For 链(用于追踪代理链路)
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 关键!反向代理到本地 Spring Boot 服务
# 注意:proxy_pass 末尾的斜杠影响路径转发行为:
# - proxy_pass http://localhost:8080/; -> /prod-api/login 转发为 http://localhost:8080/login
# - proxy_pass http://localhost:8080; -> /prod-api/login 转发为 http://localhost:8080/prod-api/login
# 在此例中我们希望去掉前缀 /prod-api/,所以使用带斜杠的 proxy_pass(即 http://localhost:8080/)。
proxy_pass http://localhost:8080/;
}
# -------------------------------------------------
# location ~ ^/v3/api-docs/(.*) :代理 Swagger/OpenAPI 文档
# -------------------------------------------------
# 使用正则匹配以 /v3/api-docs/ 开头的路径
# $1 是正则捕获组,用于保留原始路径参数
location ~ ^/v3/api-docs/(.*) {
# 将请求转发到后端对应的 Swagger 接口
# 例如:/v3/api-docs/system/user → 转发到 http://localhost:8080/v3/api-docs/system/user
proxy_pass http://localhost:8080/v3/api-docs/$1;
}
# -------------------------------------------------
# 错误页面配置
# -------------------------------------------------
# 当发生 500/502/503/504 错误时,返回 /50x.html 页面
error_page 500 502 503 504 /50x.html;
# 精确匹配 /50x.html 请求
location = /50x.html {
# 使用 Nginx 默认的 html 目录(通常是 /usr/share/nginx/html/)
root html;
}
}
}
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# 踩坑小记
笔者利用脚本部署后端时,遇到这个编码问题
- 这是典型的 Windows 与 Linux 换行符不兼容问题
- 解决方法参考上文中的 编码格式问题.解决方案
-bash: ./ry.sh: /bin/sh^M: 坏的解释器: 没有那个文件或目录
1
上次更新: 2025/11/28 17:48:16