部署总览
本章面向运维人员,讲清「RuoYi Plus Market」这套系统怎么落地到一台服务器上:有哪些产物、三种部署方式怎么选、上线前要检查什么、第一次上线必须替换哪些凭据。
平台形态(官方版 / 用户版)与目录集中等运行期概念见 /architecture/catalog-and-edition,本章只讲部署动作本身。
三种部署方式
| jar 直跑 | 手工 Docker | 1Panel「本地应用」 | |
|---|---|---|---|
| 适用场景 | 开发验证、单机自用、排障时并排起第二个实例 | 已有 Docker 与运维规范,不需要面板 | 生产交付、需要面板统一管中间件与备份 |
| 中间件 | 自己装 MySQL / Redis / RabbitMQ | 自己装或用外部实例 | 面板应用商店选服务,或填外部地址 |
| 前端 | npm run dev 或自己起 nginx | 用 deploy/docker/frontend 构建镜像 | 包内镜像 |
| 初始化 SQL | 手工导入 script/sql/ | 手工导入 | entrypoint.sh 首次启动自动导入 |
| 产物落位 | 宿主工作目录下的相对路径 | 容器挂载卷 | 容器挂载卷 |
| 升级方式 | 换 jar + 重启(先清旧插件 jar) | 重建镜像 + docker compose up -d | 面板换镜像 tag / 换包内 SQL |
三种方式跑的是同一个 jar、同一份前端、同一套配置项,差别只在「谁来提供中间件、谁来挂卷、谁来跑初始化 SQL」。
先读这一条
deploy/ 之下没有独立的 docker-compose.yml。唯一的 compose 文件在 1Panel 应用包内:
RuoYi-Vue-Plus/deploy/1panel/apps/<包名>/<版本>/docker-compose.ymldeploy/docker/ 是镜像构建上下文(Dockerfile + entrypoint + 待 COPY 的产物),不是 compose 目录。想手工 Docker 部署,就用包内那份 compose 当模板,或直接 docker build + docker run。
四类部署产物
| 产物 | 来源 | 落位位置 | 谁读它 |
|---|---|---|---|
| 后端 jar | mvn -pl ruoyi-admin -am -B install -DskipTests → ruoyi-admin/target/ruoyi-admin.jar | 直跑:随工作目录;容器:/app/app.jar | JVM |
| 前端 dist | npm run build:prod 或 vite build --mode docker → plus-ui/dist | nginx 静态根:容器 /usr/share/nginx/html | 浏览器 |
| 插件 jar | 应用包里的 backend/*.jar,由 /app/version/{id}/deploy 在运行期释放 | app-market.deploy.plugin-dir(容器内 /app/plugins-dist) | -Dloader.path 与插件运行时 |
| 远程应用前端产物 | 应用包里的 frontend/**,同样运行期释放 | app-market.deploy.frontend-dir(容器内 /app/remote-apps) | nginx 的 /remote-apps/ |
前两类是部署时准备好的静态产物;后两类是运行期由后端从市场拉包写进磁盘的,所以它们所在目录必须与后端配置、nginx 配置、启动参数三处对齐。四类产物的完整链路见 /architecture/lifecycle。
部署前检查清单
- [ ] MySQL 8.x 已就绪,库已建好(或已授权应用账号建库),排序规则用
utf8mb4_0900_ai_ci(MariaDB 没有这个排序规则,不要用) - [ ] Redis 6+ 已就绪,已设密码(1Panel 里 Redis 没密码时安装表单的必填项会是空的)
- [ ] RabbitMQ 选填:不装也不影响启动,只是消息中心 / 站内信不可用
- [ ] 平台初始化 SQL 已备好:
script/sql/platform_init.sql(打包路线由build-1panel.ps1拼成01-platform.sql) - [ ] 签名密钥已生成:
plugins/package.ps1 -Keygen,私钥只留在发布方(plugins/keys/已 gitignore) - [ ] 公钥已贴进
app-market.security.public-key,并重建宿主 + 重启(公钥是启动期读入的) - [ ]
app-market.security.mode的取值与「公钥是否已配」自洽:没配公钥就切enforce会拒绝所有包 - [ ]
app-market.deploy.plugin-dir与启动参数-Dloader.path指向同一个目录 - [ ]
app-market.deploy.frontend-dir与 nginx/remote-apps/的物理路径是同一个卷 - [ ] 对象存储已启用(系统工具 → 系统配置 → 文件存储配置);不配则上传应用包与图片会失败
- [ ] 升级前已按 /deploy/upgrade 的备份清单做过备份
- [ ] 所有真实凭据已按下一节的清单替换(不要在正式环境沿用仓库里的开发值)
第一次上线必须做的脱敏
仓库里带着一套开发验证阶段的凭据。正式对外之前,下面这些位置必须逐个替换。本页不列真实值,遇到就写占位符并替换。
| 位置 | 换成什么 | 不做会怎样 |
|---|---|---|
application-prod.yml 的数据源 url / username / password | 自己的库地址与账号密码(或用环境变量覆盖) | 连到别人的库;密码泄露 |
| Redis 连接信息与密码 | 自己的实例与密码 | 同上 |
| RabbitMQ 连接信息与密码 | 自己的实例与密码 | 同上 |
| Sa-Token / JWT 令牌密钥 | 自己生成的长随机串 | 任何人可伪造登录态 |
api-decrypt 的 RSA 公私钥(前端 .env.* 与后端配置成对) | 重新生成一对并前后端同时换 | 接口加密形同虚设 |
app-market.security.public-key | 自己 keygen 出来的公钥(源码注释已写明现有值是开发验证阶段生成的) | 别人能用旧私钥签出被你认可的包 |
plugins/keys/private.pem | 自己的私钥,且留在发布方、备份到仓库之外 | 私钥丢了只能重新签发所有包 |
前端 .env.production 的 VITE_APP_BASE_API | 自己的接口地址 | 前端打到别人的环境 |
目录服务令牌 app-market.catalog.token / CATALOG_TOKEN | 长随机串(建议 openssl rand -hex 24),两端一致 | 令牌太弱等于没设;两端不一致则市场列表 500 |
application-prod.yml 里的监控中心账号 / 密码、SnailJob 接入令牌 | 自己的值 | 监控中心认证失败或调度中心注册不上 |
凭据的三条底线
plugins/keys/已在.gitignore里 —— 不要为了"方便"把它提交进仓库;- 公钥不是秘密,可以放配置文件;私钥只留在发布方,且不要放在部署机上;
- 改完公钥 / 加密密钥这类启动期读入的值,必须重建宿主 jar 再重启,改 yml 文件本身不生效。
密钥生成、签名与「就地重签」的完整流程见 /package/signing。
相关阅读
- /deploy/backend —— 后端 jar / Docker / 1Panel 三条路线的逐条命令
- /deploy/frontend —— 前端构建模式与 nginx 的
/remote-apps/对齐 - /deploy/configuration ——
app-market:全量配置项与风险等级 - /deploy/upgrade —— 平台与应用升级、补数据脚本、回滚能力