沉梦听雨的编程指南 沉梦听雨的编程指南
首页
  • 基础篇
  • 集合篇
  • 并发篇
  • JVM
  • 新特性
  • 计算机网络
  • 操作系统
  • 数据结构与算法
  • 基础篇
  • MySql
  • Redis
  • 达梦数据库
  • Spring
  • SpringBoot
  • Mybatis
  • Shiro
  • 设计须知
  • UML画图
  • 权限校验
  • 设计模式
  • API网关
  • 网络通信
  • 消息队列
  • SpringCloud
  • 分布式事务
  • 云存储
  • 搜索引擎
  • 多媒体框架
  • 虚拟机
  • 开发工具篇
  • 工具库篇
  • 开发技巧篇
  • 工具类系列
  • 随笔
  • 前端环境搭建
  • HTML与CSS
  • JS学习
  • Axios入门
  • Vue Router入门
  • Pinia入门
  • Vue3入门
  • Vue3进阶
  • 黑马Vue3
  • 脚手架搭建
  • 瑞吉外卖
  • 黑马点评
  • vue-blog
  • 沉梦接口开放平台
  • 用户中心
  • 聚合搜索平台
  • 仿12306项目
  • 壁纸小程序项目
  • RuoYi-Vue
  • 博客搭建
  • 网站收藏箱
  • 断墨寻径摘录
  • 费曼学习法
Github (opens new window)

沉梦听雨

时间是最好的浸渍剂,而沉淀是最好的提纯器🚀
首页
  • 基础篇
  • 集合篇
  • 并发篇
  • JVM
  • 新特性
  • 计算机网络
  • 操作系统
  • 数据结构与算法
  • 基础篇
  • MySql
  • Redis
  • 达梦数据库
  • Spring
  • SpringBoot
  • Mybatis
  • Shiro
  • 设计须知
  • UML画图
  • 权限校验
  • 设计模式
  • API网关
  • 网络通信
  • 消息队列
  • SpringCloud
  • 分布式事务
  • 云存储
  • 搜索引擎
  • 多媒体框架
  • 虚拟机
  • 开发工具篇
  • 工具库篇
  • 开发技巧篇
  • 工具类系列
  • 随笔
  • 前端环境搭建
  • HTML与CSS
  • JS学习
  • Axios入门
  • Vue Router入门
  • Pinia入门
  • Vue3入门
  • Vue3进阶
  • 黑马Vue3
  • 脚手架搭建
  • 瑞吉外卖
  • 黑马点评
  • vue-blog
  • 沉梦接口开放平台
  • 用户中心
  • 聚合搜索平台
  • 仿12306项目
  • 壁纸小程序项目
  • RuoYi-Vue
  • 博客搭建
  • 网站收藏箱
  • 断墨寻径摘录
  • 费曼学习法
Github (opens new window)
  • 脚手架搭建
  • 瑞吉外卖

  • 黑马点评

  • vue-blog

  • 沉梦接口开放平台

  • 用户中心

  • 聚合搜索平台

  • 仿12306项目

  • 壁纸小程序项目

  • RuoYi-Vue

    • 若依学习笔记
    • ruoyi-vue部署篇
      • 官方文档
      • 后端部署
        • 部署步骤
        • 脚本部署
        • 手动部署
        • 确认 jar 包是否启动成功
        • 脚本文件
        • 配置优化
        • 编码格式问题
        • 日志文件生成
      • 前端部署
        • 本地构建前端
        • 将 dist 上传到服务器
        • 配置 Nginx 静态服务和 API 地址代理
      • nginx 配置
        • 整体结构说明
        • 如何查看 Nginx 实际加载了哪些配置?
        • 重载 Nginx
        • 开放防火墙端口(如 80)
        • ruoyi 官方配置解析
      • 踩坑小记
  • 项目笔记
  • RuoYi-Vue
沉梦听雨
2025-11-06
目录

ruoyi-vue部署篇

# ruoyi-vue 部署篇

# 官方文档

  • 环境部署 | RuoYi (opens new window)
  • Nginx中文手册 | Nginx 教程 (opens new window)

# 后端部署

# 部署步骤

# 脚本部署

  1. 使用 ry.sh 脚本部署
  2. 将项目打包成 ruoyi-admin.jar 文件
  3. 把 ruoyi-admin.jar 和 ry.sh 脚本上传到服务器同一目录下
  4. 给 ry.sh 脚本添加执行权限:
chmod +x ry.sh
1

使用以下命令控制服务:

./ry.sh start    # 启动服务
./ry.sh stop     # 停止服务
./ry.sh restart  # 重启服务
./ry.sh status   # 查看服务状态
1
2
3
4

# 手动部署

  1. 将 ruoyi-admin.jar 上传到服务器
  2. 在服务器上运行命令启动服务(日志输出路径自定义):
# 日志输出路径可自定义文件名
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

指令分析:

  • > 是标准输出(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 等工具。

指令作用解释:

  1. 使用 nohup 启动 Java 应用,使其忽略 hangup(SIGHUP)信号(即终端关闭不会杀死它);
  2. 所有正常输出(stdout)和错误输出(stderr)都被丢弃,不写入任何日志文件;
  3. 进程在后台运行,命令执行后立即返回 shell 提示符。

# 确认 jar 包是否启动成功

有以下几种方法:

  1. 使用脚本查看状态

    • ./ry.sh status
  2. 手动检查进程

    • ps -ef | grep ruoyi-admin.jar 查单个
    • ps -ef | grep java 查全部
  3. 检查端口占用

    • netstat -tlnp | grep 8080
  4. 查看日志文件

  5. 访问健康检查接口

    • curl http://localhost:8080/actuator/health
  6. 测试业务接口

    • 生成验证码接口: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

# 编码格式问题

将 Windows 下编辑或生成的 ry.sh 脚本直接复制到 Linux 服务器后,换行符和编码格式不兼容会导致脚本无法正常执行。

主要问题通常有两个

  1. 换行符不同(最常见)
    • Windows 使用 CRLF(\r\n)
    • Linux 使用 LF(\n)
    • 在 Linux 中运行含 \r 的脚本会报错
  2. 文件编码问题(较少见但可能)
    • 如果文件保存为 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
  • 转换脚本文件:
dos2unix ry.sh
1
  • 添加执行权限并运行:
chmod +x ry.sh
./ry.sh
1
2

2、方法二:用 sed 手动删除 \r(无需安装工具)

  • 原理:sed 删除每行末尾的回车符 \r(即 Windows 的 CR)。
sed -i 's/\r$//' ry.sh
chmod +x ry.sh
./ry.sh
1
2
3

3、方法三:重新写脚本文件

# 编写新的脚本文件
vim ry-new.sh

# 将脚本内容复制进去

# 输入 :wq 指令,保存并退出
1
2
3
4
5
6

# 日志文件生成

  • 官方脚本方式启动,只是定义了日志文件存放路径,默认是没有输入到对于的日志文件中的。
  • 实际的文件存储位置,参考项目代码中的 logback.xml 文件
    <!-- 日志存放路径 -->
	<property name="log.path" value="/home/ruoyi/logs" />
1
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

# 将 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

# 配置 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

# 如何查看 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

# 重载 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

# 开放防火墙端口(如 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

# 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

# 踩坑小记

笔者利用脚本部署后端时,遇到这个编码问题

  • 这是典型的 Windows 与 Linux 换行符不兼容问题
  • 解决方法参考上文中的 编码格式问题.解决方案
-bash: ./ry.sh: /bin/sh^M: 坏的解释器: 没有那个文件或目录
1
上次更新: 2025/11/28 17:48:16
若依学习笔记

← 若依学习笔记

Theme by Vdoing | Copyright © 2023-2025 沉梦听雨 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式