Skip to content

部署 ​

本页是「部署」这一章的入口,只回答一件事:把 Wujies 无界平台装到一台服务器上,要装哪几个包、按什么顺序、装完必须做什么。

当前的交付方式是 1Panel 应用包 + docker compose + 外部中间件。平台自己只提供两个容器(前端 nginx + 后端),MySQL / Redis / RabbitMQ 不在包内、也不打进镜像 —— 它们在安装表单里「从 1Panel 应用商店选一个已装的服务」或「填你自己的外部实例地址」。jar 直跑只用于开发验证与排障(入口是 script/prune/start-host.ps1),交付与生产走 1Panel 包。

先分清两类「包」,它们不是一回事

平台包(本页)业务应用包
是什么把平台装成 1Panel 本地应用(前端 nginx + 后端 jar)应用市场里的应用:mall / gallery / im / member / pay …
谁产出wujies-platform/deploy/tools/build-1panel.ps1发布方 wujies/wujies-plugins/package.ps1
产物deploy/dist/1panel/wujies-platform-1panel-5.6.3.tar.gz<code>-<version>.zip(含 signature.txt)
装在哪1Panel → 应用商店 → 本地应用平台内「应用上架」上传,再在「应用市场」安装

两者通过应用目录衔接:业务应用包上架并发布后,目录里才有它的版本,市场里才有东西可装。 这条链路的起点是 打包与上架。

交付产物:四个 1Panel 应用包 ​

包是什么什么时候装
wujies-platform-server官方版:目录在自己的库里(catalog.mode=local)、含上架端、对外提供 /app/catalog/**单机自用;或多部署里那台「目录服务」
wujies-platform-client用户版:没有上架端,目录从官方版读(catalog.mode=remote,写死)交付给客户,且已经有一台官方版在跑
wujies-snailjob-server定时任务调度中心(SnailJob 服务端 + 控制台 /snail-job)要跑定时任务:订单自动取消 / 自动收货、优惠券状态与过期、促销启停、统计刷新、积分过期
wujies-monitor-admin服务监控中心(Spring Boot Admin,/admin)想在线看健康、JVM、日志级别、配置

后两个是独立的应用包,各有自己的容器与(调度中心还有)自己的数据库。主包安装表单里填上它们的地址即启用,留空就不启用。当前端在同一个 1panel-network 上时,地址固定填 snailjob-server 与 http://monitor-admin:9090/admin(两个包各带一个固定网络别名,不用去查面板随机生成的容器名)。

官方版与用户版是同一个 jar 靠配置扮演两个角色,不是两个 fork —— 差别只在目录从哪读、上架端开不开。选型与目录集中见 多部署与目录服务。

主包里有什么 ​

主包只有两个容器:

服务容器名端口说明
frontend(主服务)${CONTAINER_NAME}${PANEL_APP_PORT_HTTP} → 80nginx:托管前端 dist、反代 /prod-api/ 到后端、按 /remote-apps/ 提供远程应用产物
backend${CONTAINER_NAME}-backend8080;官方版额外对公映射 ${PANEL_APP_PORT_API}后端 jar,启动前先解析中间件地址、首次启动初始化数据库

中间件一个都不在包里。每个中间件在安装表单里都是两条路,解析规则是「外部字段非空 → 用外部;否则用面板选的服务;都空 → 容器启动失败并打印原因」,这段逻辑写在 deploy/docker/backend/entrypoint.sh 里(compose 与 Spring 都表达不了这种条件)。

后端容器里有两个卷必须记住,它们把「后端写产物」和「nginx 读产物」连起来:

宿主(相对应用目录)容器内谁在用
./data/plugins-dist/app/plugins-dist插件 jar 落位目录 = app-market.deploy.plugin-dir,运行期由插件运行时加载
./data/remote-apps/app/remote-apps(后端读写)、/var/www/remote-apps:ro(nginx 只读)远程应用前端产物 = app-market.deploy.frontend-dir

这两行挂的不是同一个宿主目录,表现就是「安装成功、菜单也在,点进去 404」。完整卷表与配置项见 后端部署 与 前端部署与 Nginx。

部署要走完的六步 ​

① 打包(开发机 / CI) ​

powershell
# 全量:前端 vite build --mode docker + 后端 mvn install + 组装 + 打 tar.gz
powershell -ExecutionPolicy Bypass -File wujies-platform\deploy\tools\build-1panel.ps1

# 只改了后端 Java
powershell -ExecutionPolicy Bypass -File wujies-platform\deploy\tools\build-1panel.ps1 -SkipFrontend

# 只改了 SQL / data.yml / compose(最常用,几十秒,不用重建镜像)
powershell -ExecutionPolicy Bypass -File wujies-platform\deploy\tools\build-1panel.ps1 -SkipFrontend -SkipBackend

前提是 Node 22+、JDK 17($env:JAVA_HOME)、Maven。产出在 deploy/dist/1panel/:apps/(四个包)、docker/(四个镜像构建上下文)、wujies-platform-1panel-5.6.3.tar.gz(上传到服务器的那一个文件)。

  • ⚠️ build-1panel.ps1 必须保持 UTF-8 with BOM:Windows PowerShell 5.1 对无 BOM 的脚本按 ANSI 解码,中文注释会连带吃掉下一行。
  • 改版本号要同时动四处:脚本的 $Version、包内 5.6.x/ 目录名、compose 里的镜像 tag、deploy/tools/gen-appstore-data.mjs 的 VERSION。
  • 包里的初始化 SQL 是文件(sql/files/,只读挂进容器),不是打进镜像的;只有 jar 与前端 dist/ 需要重建镜像。

② 构建镜像(有 Docker 的那台机器) ​

1Panel 本地应用只负责拉镜像,镜像要你自己构建:

bash
cd /root/pkg/docker/backend  && docker build -t wujies-platform/backend:5.6.3 .
cd ../frontend               && docker build -t wujies-platform/frontend:5.6.3 .
# 只有装了可加装的两个包才需要下面两个
cd ../snailjob               && docker build -t wujies-platform/snailjob-server:5.6.3 .
cd ../monitor                && docker build -t wujies-platform/monitor-admin:5.6.3 .
  • 面板安装时总会先 docker pull 一遍。日志出现 拉取镜像 失败 … denied 紧跟着「镜像已存在,使用存量镜像」不是错误(wujies-platform/* 会被解析成 Docker Hub 上的同名命名空间);想省掉那一分钟左右,在安装抽屉的「高级」里取消勾选「拉取镜像」。
  • 多机部署 / 上架官方商店必须让拉取能成功:把镜像 tag 到你自己的仓库并推到可公开拉取的地方,同时把包内 compose 的 image: 一起换掉。私有仓库还要先在面板「容器 → 仓库」里加凭据。

③ 传进面板 ​

bash
scp wujies-platform-1panel-5.6.3.tar.gz root@<host>:/root/
ssh root@<host> 'mkdir -p /root/pkg && tar -xzf /root/wujies-platform-1panel-5.6.3.tar.gz -C /root/pkg'
ssh root@<host> 'cp -r /root/pkg/apps/* /opt/1panel/resource/apps/local/ && chmod -R a+rX /opt/1panel/resource/apps/local/wujies-platform-*'

然后在面板里 应用商店 → 本地应用 → 同步/刷新,四个包就出现了。

别用 scp 直接传进资源目录

Windows 的 OpenSSH scp 建出来的目录是 0700,容器里的非 root 用户读不到挂载进去的文件。传完一律 chmod -R a+rX;走 tar 解包不会踩(推荐)。

④ 装主包,填安装表单 ​

分组字段要点
数据库数据库服务下拉只提供 MySQL:平台初始化 SQL 通篇 utf8mb4_0900_ai_ci,MariaDB 没有这个排序规则,装了也没用
数据库名 / 用户 / 密码点安装时面板自动生成 wujies_<6位随机> 并自动建库 + 授权。⚠️ 装完别改:这三个值同时写在 MySQL 里和容器的 .env 里,只改一边就是「等待 MySQL 超时」
数据库地址(外部)等填了优先用外部(云数据库、已有集群)。⚠️ 外部库要你自己先建库并授权,面板不会替你建,入口脚本只会 CREATE DATABASE IF NOT EXISTS
RedisRedis 服务必填。⚠️ 面板里那个 Redis 没设密码时这一栏是空的、而它是必填项 —— 先去给 Redis 设密码
RabbitMQRabbitMQ 服务等选填,留空应用照常启动,只是消息中心 / 站内信不可用。⚠️ 面板不会把账号密码带过来,默认按官方应用的 rabbitmq / rabbitmq 预填,改过就去「应用商店 → 已安装 → RabbitMQ → 参数」抄
访问外部访问地址形如 http://<host>:8080,第三方登录回调等对外链接用它
前端访问端口 / 后端接口端口官方版要暴露后端端口给用户版读目录(默认 18080);用户版不需要
应用市场应用包检查模式默认 warn。切 enforce 的前提是 public-key 已配置 —— 没配公钥时 enforce 会拒绝所有包(包括你自己签的)
目录服务令牌用户版必填且要手抄官方版那个值;两端不一致的表现是市场列表 500「目录接口令牌校验失败」
可加装调度中心地址 / 监控中心地址留空 = 不启用。装了那两个包就填 snailjob-server 与 http://monitor-admin:9090/admin

官方版与用户版的两个必配对项

  • 用户版的「官方版地址」要写官方版后端端口(http://<官方版IP>:18080),不是前端端口;
  • 两端的「目录服务令牌」必须是同一个长随机串。

用户版写死 catalog.mode=remote:它是 client 形态,配 local 会直接启动失败并写明该改哪一行(MarketEditionStartupCheck)。

⑤ 看首次启动的初始化日志 ​

bash
# 先定位实例目录(<实例名> 就是面板「已安装」里那个名字),形如
#   /opt/1panel/apps/local/<包名>/<实例名>/
cd /opt/1panel/apps/local/wujies-platform-server/<实例名>
docker compose ps
docker compose logs --tail=200 backend | grep '\[entry\]'

期望看到(全新初始化):

[entry] MySQL=mysql:3306/wujies_xxxxxx  Redis=redis:6379  RabbitMQ=rabbitmq:5672
[entry] 等待 MySQL 就绪…
[entry] 首次启动:初始化数据库 wujies_xxxxxx
[entry] 导入 01-platform.sql
[entry] 导入 02-app-market.sql
[entry] 导入 03-app-catalog.sql
[entry] 应用目录:app_info=N 行  app_version=M 行
[entry] 数据库初始化完成,已写入标记 platform.init.version=5.6.3
[entry] 启动应用(profile=prod)

顺序固定:01-platform.sql(平台表 + 平台数据)→ 02-app-market.sql(应用市场的表与列)→ 03-app-catalog.sql(应用目录种子)。判据是 sys_config 里有没有 platform.init.version 这一行(不是「有没有 sys_user 表」:半途失败的库会缺表但已有表)。

导入用 mysql --force 容忍个别语句报错,随后做两道复核:关键表全检(缺一张就不写标记、让容器失败 —— 宁可安装当场失败,也不要交付一个残库)与目录数据非空(app_info 为 0 行同样失败)。第二次启动看到的是「数据库已初始化过…跳过导入」。

重来一遍不要 DROP DATABASE

面板建库时只给了 GRANT ALL PRIVILEGES ON `wujies_xxxxxx`.*,没有全局 CREATE。库一删,入口脚本那句 CREATE DATABASE IF NOT EXISTS 就建不回来,导入全部落到不存在的库上,最后卡在「缺 N 张关键表」起不来。 要重来请清空该库里的表(保留库与授权)再重启容器;只改数据的话更省事:删掉 platform.init.version 那一行再重启,脚本本身幂等。

⑥ 装完的收尾 ​

  1. 对象存储:系统工具 → 系统配置 → 文件存储配置,启用一种(MinIO / 阿里云 / 腾讯云 / 七牛)。默认所有配置都是停用状态,所以刚装完上传应用包与图片会失败 —— 这是刻意的,不替用户决定用哪个存储。另外装了 1Panel 的 MinIO 应用时,domain 填 http://<host>:<前端端口>/minio 走本应用 nginx 反代,并把 compose 里 frontend 的 MINIO_HOST 改成 MinIO 容器名。
  2. 签名公钥与检查模式:发布方生成密钥(wujies/wujies-plugins/package.ps1 -Keygen),把公钥贴进 app-market.security.public-key,再按发布说明重建宿主 jar 并重启,最后把表单里的检查模式改成 enforce。见 密钥与签名 与 安全校验模式。
  3. 上架并安装业务应用:官方版 →「应用上架」上传业务应用包 → 建版本 → 发布;再回到「应用市场」安装。全新部署的市场里已经有第一方应用(目录种子 03-app-catalog.sql 随包),不需要重新上架一遍。
  4. 可加装的两个服务:调度中心控制台在 http://<host>:8800/snail-job/(种子账号 admin / admin,进去就改),任务定义要在「任务管理 → 导入」里导 script/sql/snailjob-task-export.json;监控中心在 http://<host>:9090/admin(HTTP Basic,账号密码与主包表单里填的一致)。⚠️ 两者都是「端口 + context-path」,根路径 404 是正常的,不是装坏了。

部署前检查清单 ​

  • [ ] 1Panel 已就绪;面板里已装 MySQL(8.x,排序规则 utf8mb4_0900_ai_ci)与 Redis(已设密码);RabbitMQ 选填
  • [ ] 一台有 Docker 的机器用于构建镜像(或镜像已推到可拉取的仓库)
  • [ ] 打包机满足 Node 22+ / JDK 17 / Maven,且 build-1panel.ps1 仍是 UTF-8 with BOM
  • [ ] 服务器内存按主包 README 的规格准备(后端 + nginx ≥ 2GB,中间件另计)
  • [ ] 包里有 sql/files/03-app-catalog.sql(缺了打包时会 Write-Warning,新部署的市场会是空的)
  • [ ] 多部署时:官方版与用户版用的是同一个目录服务令牌,且用户版填的是官方版后端端口
  • [ ] 对象存储、签名公钥这两件收尾事项已经安排人做(否则上传会失败、enforce 会拒包)
  • [ ] 动过已有部署前看过 升级与补丁 的备份清单

上线前必须替换的凭据 ​

1Panel 路线下,库名 / 账号 / 密码、目录服务令牌都由面板随机生成,不用你操心。下面这些是仓库里带着的开发验证值,正式对外前必须逐个换掉;本页只列位置。

位置换成什么不做会怎样
application.yml 的 sa-token.jwt-secret-key(仓库里是 abcdefghijklmnopqrstuvwxyz)自己生成的长随机串任何人可伪造登录态
api-decrypt.publicKey / privateKey(与前端 .env.* 成对,api-decrypt.enabled 当前为 false)重新生成一对,前后端同时换,要启用接口加密就先换接口加密形同虚设
app-market.security.public-key自己 keygen 出来的公钥(源码注释已写明现有值是开发验证阶段生成的)别人能用旧私钥签出被你认可的包
wujies/wujies-plugins/keys/private.pem自己的私钥,留在发布方并备份到仓库之外换钥会让旧钥签过的包全部作废;私钥丢了只能重签所有包
前端 .env.production 的 VITE_APP_BASE_API自己的接口地址(容器路线用的是 .env.docker 的 /prod-api,不受影响)前端打到别人的环境
调度中心控制台账号(script/sql/ry_job.sql 的种子是 admin / admin)与监控中心账号密码自己的值默认口令被人登进控制台
application-prod.yml 里的数据源 / Redis / RabbitMQ / 监控中心账号 / SnailJob 接入令牌jar 直跑时必须自己改;1Panel 路线由环境变量覆盖,不用管连到开发库;密码泄露

三条底线

  1. wujies/wujies-plugins/keys/ 已在 .gitignore 里 —— 不要为了「方便」把它提交进仓库;
  2. 公钥不是秘密,可以放配置文件;私钥只留在发布方,且不要放在部署机上;
  3. public-key、api-decrypt 的密钥、sa-token.jwt-secret-key 都是启动期读入的 —— 改完必须重建宿主 jar 再重启,只改 yml 文件不生效。

相关阅读 ​

  • 后端部署 —— 包结构、镜像与卷挂载、中间件「选服务 / 填外部」的解析规则、首次初始化逻辑
  • 前端部署与 Nginx —— 构建模式,以及 /remote-apps/ 四处路径的对齐
  • 配置项 —— app-market: 全量配置项与风险等级
  • 多部署与目录服务 —— 官方版 / 用户版、目录集中、共享令牌
  • 升级与补丁 —— 平台表结构升级、应用升级、存量补数据脚本、备份清单
  • 打包与上架 —— 业务应用包怎么打、怎么签、怎么上架
  • 故障排查 —— 装不上 / 起不来时按症状查原因
  • 备份与安全 —— 备什么、密钥纪律

我们坚信,即使再复杂的技术,也可以用清晰、干练、易懂的文字描述清楚。如果你在阅读时有难以理解的章节,那一定是我们还没有优化好它 —— 欢迎反馈。