后端部署
本文是 1.x 的归档文档(冻结于 1.x)。该分支只接收勘误修正, 内容基本不再变动;文中的源码路径、配置项与版本号均以 1.x 为准,不建议用于新项目。
新项目请查看 5.x 最新文档。已在 1.x 上运行的项目,本文仍是可靠依据。
本页只讲后端:wujies-admin.jar 怎么打出来、三种起法(主机直跑 / 手工 Docker / 1Panel 本地应用)各敲什么命令、首次启动的初始化 SQL 由谁跑、中间件地址从哪来。
运行期的机制不在这里重复:平台形态(官方版 / 用户版)与目录集中见 /advanced/catalog-and-edition,插件的加载与回收见 /advanced/plugin-runtime,app-market: 配置项逐条说明见 /deploy/configuration。
先认清三个目录
三个仓库没有共同 git 根,各自分支、各自提交。本页所有命令都按这个布局写(平台的上游出处是 RuoYi-Vue-Plus,更名后的模块与路径一律以 wujies-* 为准):
| 仓库 | 目录 | 内容 |
|---|---|---|
| 后端 | wujies-platform/ | Java / Spring Boot + script/sql/** + deploy/** |
| 插件 | wujies/wujies-plugins/ | 插件本体 + 插件前端工程 + package.ps1 |
| 宿主前端 | plus-ui/ | Vue 3 / Vite —— ⚠️ 它的 package.json 里 name 写的是 wujies-admin,别被这个名字带偏 |
平台里没有 *-api 契约模块(2026-09-30 起为 0 个),也没有 wujies-job / wujies-demo / wujies-generator。每个业务应用都是自包含的:实体 / BO / VO / Mapper 接口与 Mapper XML / Service / controller / app.json / migrations/ 全在插件仓库的 wujies-<app>/ 下,平台对 cn.wujies.<app>.* 的 Java 引用为 0。所以在这里找不到 mall / gallery 之类的业务代码,这是设计如此 —— 不变量见 /plugin-dev/basics/invariants。
后端产物:一个可运行 jar
启动模块是 wujies-platform/wujies-admin/,产物固定为:
wujies-platform/wujies-admin/target/wujies-admin.jar它的依赖链不含任何业务应用:插件 jar 与远程应用前端产物都是运行期由应用市场落位到磁盘的(见 /advanced/lifecycle)。所以"部署后端"始终是"部署一个 jar + 给它两个可写目录"。
这两个目录必须记住 —— 在 application.yml 里是相对路径,相对启动时的工作目录:
| 配置项 | 默认值 | 容器内 |
|---|---|---|
app-market.deploy.plugin-dir | plugins-dist | /app/plugins-dist |
app-market.deploy.frontend-dir | ../wujies-admin/app-market-dist/remote-apps | /app/remote-apps |
⚠️ 这里的 wujies-admin 是工作区顶层那个只放 app-market-dist/ 的目录(前端产物的落位处),既不是后端模块 wujies-platform/wujies-admin/,也不是宿主前端仓库 plus-ui/——三处同名,按路径判断。
编译与打包
# 环境(本机没有把 JDK / Maven 加进 PATH 时)
$env:JAVA_HOME = "C:\Users\<you>\.jdks\corretto-23.0.2"
$mvn = "C:\Program Files\JetBrains\IntelliJ IDEA 2025.3.3\plugins\maven\lib\maven3\bin\mvn.cmd"
# 全量编译(根 pom 默认 skipTests=true,编译不会跑测试)
& $mvn -B -q compile -DskipTests
# 打可运行 jar —— 改了后端代码必须做这一步才能验证
& $mvn -pl wujies-admin -am -B install -DskipTestsinstall会把依赖装进本地仓库,运行中的 JVM 会锁住旧 jar:服务还跑着的时候执行它会中途失败(Windows 上尤其明显)。先停服务,或先只做compile。- 跑单模块测试要显式打开跳过开关并指定 profile:
& $mvn -pl wujies-modules/wujies-app-market -B test "-DskipTests=false" "-Dprofiles.active=dev"。
profile 是构建期写进 jar 的,默认是 dev
application.yml 里的 spring.profiles.active: @profiles.active@ 是 Maven 过滤占位符(根 pom 对 application* 开了 filtering),构建时被替换。根 pom 有 local / dev / prod 三个 profile,其中 dev 是 activeByDefault:
| 构建命令 | jar 内写死的 profile |
|---|---|
mvn -pl wujies-admin -am install | dev |
mvn -pl wujies-admin -am install -Pprod | prod |
deploy/tools/build-1panel.ps1 走的是第一条(没有 -Pprod),容器里靠 compose 的 SPRING_PROFILES_ACTIVE: prod 覆盖(环境变量优先级高于 jar 内 yml)。直跑时没有这层覆盖,必须自己传 -Dspring.profiles.active=prod,否则起的是 dev 配置。
⚠️ application-prod.yml 里带着一整套开发验证阶段的连接信息(数据库、Redis、RabbitMQ 的地址与密码都写在文件里)。正式环境必须先按 /deploy/index 的脱敏清单替换,或用环境变量覆盖。
路线一:主机直跑
工作目录必须是 wujies-platform/(上面两个目录是相对路径):
cd wujies-platform
java "-Dloader.path=plugins-dist" "-Dspring.profiles.active=prod" -jar wujies-admin\target\wujies-admin.jar四个必须知道的点:
| 点 | 说明 |
|---|---|
-Dloader.path 的引号不能省 | PowerShell 会把 -Dloader.path=x 拆成 /path=x,报 ClassNotFoundException: /path=plugins-dist |
工作目录必须是 wujies-platform | plugin-dir 与 frontend-dir 都是相对路径;工作目录错了会把产物写到别处 |
| profile 必须显式传 | 见上一节:jar 内默认是 dev |
插件运行时开关只能走 -D | -Dapp-market.plugin-runtime.enabled=false 才能退回旧的共享类加载器行为;写进 yml 无效——启动器在 Spring 之前执行,读的是系统属性 |
-Dloader.path 只加载该目录根下的 jar,不递归子目录(所以迁移脚本的 migrations/ 子目录是安全的)。同一个 appCode 名下留着两个版本 jar 也不会再直接把服务打挂:2026-10-02 起启动器与插件运行时都按 active-plugins.txt 选版本,不在清单里的 jar 刻意不挂载;读不到或为空时不过滤,退回改造前的宽容行为。细节见 /advanced/plugin-runtime。
启动脚本:script/prune/start-host.ps1
推荐用它代替手敲 java:它先清理上一版插件 jar,再按正确的工作目录 / profile / loader.path 启动,jar 不存在时还会自动打包。
# 默认:清旧插件 jar -> 用已有 jar 启动
powershell -NoProfile -ExecutionPolicy Bypass -File wujies-platform\script\prune\start-host.ps1
# 启动前重新打包 wujies-admin
powershell ... -File wujies-platform\script\prune\start-host.ps1 -Build
# 换端口(例如并排起第二个实例做验证)
powershell ... -File wujies-platform\script\prune\start-host.ps1 -Port 8087
# 不加载插件,用于排查「没有插件时宿主是否正常」
powershell ... -File wujies-platform\script\prune\start-host.ps1 -NoPlugin全部参数:
| 参数 | 默认 | 作用 |
|---|---|---|
-PluginDir | plugins-dist | 插件落位目录,必须与 -Dloader.path 一致 |
-Profile | prod | Spring profile |
-Build | 关 | 启动前执行 mvn -pl wujies-admin -am -B package -DskipTests |
-SkipPrune | 关 | 启动前不清理旧插件 jar |
-NoPlugin | 关 | 不传 -Dloader.path,即不加载任何插件 |
-Port | 空 | 追加 -Dserver.port=<Port> |
脚本会自己推断 JDK(JAVA_HOME,否则扫 %USERPROFILE%\.jdks)与 Maven(PATH,否则扫 C:\Program Files\JetBrains 下的 mvn.cmd),并把工作目录切到 wujies-platform。
⚠️ 脚本头部注释里的用法示例还写着 scripts\start-host.ps1(旧路径),实际文件在 script\prune\ 下——以文件位置为准。
清理旧插件 jar
# Windows / PowerShell
powershell -NoProfile -ExecutionPolicy Bypass -File wujies-platform\script\prune\prune-plugins.ps1
powershell ... -File wujies-platform\script\prune\prune-plugins.ps1 -PluginDir D:\app\plugins-dist
powershell ... -File wujies-platform\script\prune\prune-plugins.ps1 -DryRun# Linux / macOS(容器或只读挂载场景的兜底)
bash wujies-platform/script/prune/prune-plugins.sh
PLUGIN_DIR=/opt/app/plugins-dist bash wujies-platform/script/prune/prune-plugins.sh
DRY_RUN=1 bash wujies-platform/script/prune/prune-plugins.sh| 脚本 | 参数 | 作用 |
|---|---|---|
prune-plugins.ps1 | -PluginDir(留空自动推断为 <仓库根>/plugins-dist)、-DryRun(只报告不删) | 按 active-plugins.txt 只删「同 appCode 下非当前生效版本」的 jar |
prune-plugins.sh | 环境变量 PLUGIN_DIR、DRY_RUN | 同上,Bash 版本 |
判定依据是部署时写下的 active-plugins.txt(一行一条 appCode=jarFileName)。手工放进来的 jar、不属于任何已登记应用的 jar 一律不碰;没有这个文件说明还没通过应用市场部署过后端产物,脚本直接跳过。被 JVM 占用的 jar 删不掉时脚本会告警并返回非 0——这是「服务还在跑」的正常现象,不是脚本故障。
路线二:手工 Docker
deploy/docker/ 下是镜像构建上下文(Dockerfile + entrypoint + 待 COPY 的产物),不是 compose 目录:仓库里没有独立的 compose 文件,唯一一份在 1Panel 应用包内(deploy/1panel/apps/<包名>/<版本>/docker-compose.yml,见 /deploy/index)。镜像里不做构建——先在开发机打好 jar,再 COPY 进去。
| 镜像 | 上下文目录 | 基础镜像 | 端口 | 关键点 |
|---|---|---|---|---|
wujies-platform/backend | deploy/docker/backend/ | eclipse-temurin:17-jre-jammy | 8080 | 额外装 default-mysql-client(首次初始化要连库);ENTRYPOINT 用 exec 形式,保证 java 是 PID 1,能收到 SIGTERM 优雅停机 |
wujies-platform/frontend | deploy/docker/frontend/ | nginx:1.27-alpine | 80 | 预先建好 /var/www/remote-apps 与 /var/www/upload;nginx 配置必须 COPY 到 /etc/nginx/templates/default.conf.template |
wujies-platform/snailjob-server | deploy/docker/snailjob/ | eclipse-temurin:17-jre-jammy | 8800(控制台)、17888(执行器) | 自带 mysql 客户端,首次启动导入 ry_job.sql 建自己的库 |
wujies-platform/monitor-admin | deploy/docker/monitor/ | eclipse-temurin:17-jre-jammy | 9090 | 无数据库;控制台路径 /admin,HTTP Basic 认证 |
构建(build-1panel.ps1 会把四个上下文准备到 deploy/dist/1panel/docker/,产物已在同目录):
cd 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 .⚠️ wujies-platform/* 只是本地构建的镜像名,Docker Hub 上没有这个命名空间。多机部署与上架官方商店要 tag 成自己的仓库再 push,并同步改 compose 里的 image:。
数据卷
来自包内 docker-compose.yml(1Panel 约定所有数据走相对路径 ./data/...):
| 宿主相对路径 | 容器内路径 | 后端 | 前端 | 说明 |
|---|---|---|---|---|
./data/plugins-dist | /app/plugins-dist | 读写 | — | 插件 jar 落位目录,等于 app-market.deploy.plugin-dir |
./data/remote-apps | /app/remote-apps | 读写 | — | 远程应用前端产物,等于 app-market.deploy.frontend-dir |
./data/remote-apps | /var/www/remote-apps:ro | — | 只读 | 与上一行是同一个卷,nginx 按 /remote-apps/ 对外提供 |
./data/upload | /app/upload / /var/www/upload:ro | 读写 | 只读 | 本地文件存储(sys_oss_config 选 local 时用) |
./data/logs | /app/logs | 读写 | — | 日志 |
./data/temp | /app/temp | 读写 | — | 上传临时目录(SPRING_SERVLET_MULTIPART_LOCATION) |
./sql | /app/sql:ro | 只读 | — | 初始化 SQL,首次启动由 entrypoint 导入 |
后端写产物、nginx 读产物。这两行挂的不是同一个宿主目录,表现就是「安装成功、菜单也在,点进去 404」。四处路径的对齐关系见 /deploy/frontend。
JVM 参数:三个入口脚本行为不一致
这处容易照着「三个带 java 的镜像同一套语义」去配,实际不是(2026-10 按文件核对):
| 镜像 | 启动行 | 读 JAVA_OPTS 吗 |
|---|---|---|
| backend | exec java -Dapp-market.deploy.plugin-dir=… -jar /app/app.jar | 不读 |
| snailjob-server | exec java $JAVA_OPTS -jar /app/app.jar | 读 |
| monitor-admin | exec java $JAVA_OPTS -jar /app/app.jar | 读 |
所以 backend 的 Dockerfile 里那行 JAVA_OPTS="" 在后端容器上是死配置:往 compose 的 environment: 里加 JAVA_OPTS 对后端无效,堆上限仍是 JDK 默认(容器内存的 25%,或宿主内存的 1/4)。要改后端 JVM 参数有两条路:
- 不改镜像(先用这条验证):JDK 自己会读
JAVA_TOOL_OPTIONS,加到后端容器的environment:即可,启动日志里会出现Picked up JAVA_TOOL_OPTIONS: …。
environment:
# 4GB 机器:把上限写死比让 JVM 按 25% 自己猜更可控
JAVA_TOOL_OPTIONS: "-Xms256m -Xmx1024m -XX:MaxMetaspaceSize=384m"
# OOM 取证:dump 落在 /app/logs(日志卷里能取走)
# JAVA_TOOL_OPTIONS: "-Xmx1024m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/app/logs"- 改 entrypoint 并重建镜像:在
deploy/docker/backend/entrypoint.sh最后一行给java加上$JAVA_OPTS(与另外两个入口脚本对齐),docker build之后docker compose up -d。
docker logs <容器> 里能看到 Picked up JAVA_TOOL_OPTIONS(路线 1);包内 README 给的内存口径只有一条:≥ 2GB(前端 nginx + 后端,中间件按所选服务的规格另计)。
每个插件一个独立类加载器。类加载器一旦被引用泄漏,Metaspace 会一路涨到 native OOM —— 显式给一个 -XX:MaxMetaspaceSize 至少能换到一个能看懂的报错。
路线三:1Panel「本地应用」
打安装包
# 全量:plus-ui 前端 vite build --mode docker + 后端 mvn install + 组装 + 打 tar.gz
powershell -ExecutionPolicy Bypass -File wujies-platform\deploy\tools\build-1panel.ps1
# 只改了后端
powershell ... -File wujies-platform\deploy\tools\build-1panel.ps1 -SkipFrontend
# 只改了 SQL / data.yml / compose(最快,不重建镜像)
powershell ... -File wujies-platform\deploy\tools\build-1panel.ps1 -SkipFrontend -SkipBackend| 参数 | 默认 | 作用 |
|---|---|---|
-Version | 5.6.3 | 包裹版本号,同时决定目录名与 tar.gz 文件名 |
-OutDir | deploy\dist\1panel | 输出根目录 |
-SkipFrontend | 关 | 跳过 plus-ui 的前端构建,复用已有 dist/ |
-SkipBackend | 关 | 跳过后端与两个 extend jar 的构建,复用已有 jar |
-NoTar | 关 | 不打 wujies-platform-1panel-<版本>.tar.gz |
前置:Node 22+、JDK 17+($env:JAVA_HOME)、Maven(脚本先找 IDEA 自带的 mvn.cmd,找不到回落 PATH)。脚本做 5 步(第 2b 步是后加的):
- 前端:在
plus-ui/里跑node scripts/gen-runtime-shims.mjs,再vite build --mode docker(-SkipFrontend跳过); - 后端:
mvn -pl wujies-admin -am -B install -DskipTests(-SkipBackend跳过); - 2b:
mvn -pl wujies-extend/wujies-snailjob-server,wujies-extend/wujies-monitor-admin -am -B install -DskipTests—— 这两个 jar 不在wujies-admin的依赖链上,必须单独构建(-SkipBackend时一起跳过); - 组装 4 个应用包(生成各自
data.yml+ 拼初始化 SQL); - 准备 4 个 docker 构建上下文,并打
wujies-platform-1panel-<版本>.tar.gz。
产出的 4 个包(deploy/dist/1panel/apps/):
| 包 | 是什么 | 初始化 SQL |
|---|---|---|
wujies-platform-server | 官方版:目录在自己库 + 含上架端 + 对外提供 /app/catalog/** | 01-platform + 02-app-market + 03-app-catalog |
wujies-platform-client | 用户版:目录读远端(edition=client + catalog.mode=remote) | 同上 |
wujies-snailjob-server | 定时任务调度中心(自己的库) | 01-ry-job.sql |
wujies-monitor-admin | 服务监控中心 | 无(不连库) |
两个主包用的是同一个 jar,差别只在 compose 里的 APP_MARKET_EDITION / APP_MARKET_CATALOG_MODE:用户版的后端不映射对外端口(只有前端端口对公),官方版额外映射后端端口给客户端读目录。形态差异与验证见 /advanced/catalog-and-edition。
上传与安装
# 1) 上传并解包(走 tar,别用 scp 直接传进资源目录)
scp wujies-platform-1panel-5.6.3.tar.gz root@<host>:/root/
cd /root && tar -xzf wujies-platform-1panel-5.6.3.tar.gz -C /root/pkg
cp -r /root/pkg/apps/* /opt/1panel/resource/apps/local/
chmod -R a+rX /opt/1panel/resource/apps/local/wujies-platform-*要点:
- 别用 scp 直接传进
/opt/1panel/resource/apps/local/:Windows 的 OpenSSHscp建出来的目录是0700,容器里的非 root 用户读不到挂载进去的文件。传完一律chmod -R a+rX;走 tar 解包不会踩。 - 面板 → 应用商店 → 本地应用 → 同步/刷新,即可看到应用。
- 表单里 MySQL 必选、Redis 必选(且该实例要已设密码,否则必填项是空的)、RabbitMQ 可选;库名 / 账号 / 密码由面板随机生成(
random: true,default是前缀不是初值),装完就别改。 - 面板装应用时无条件先
docker pull一遍镜像:本地构建的wujies-platform/backend:5.6.3会被解析成 Docker Hub 的命名空间并denied,日志接着打「镜像已存在,使用存量镜像」并继续——这不是错误。想省掉那次超时就取消勾选安装抽屉「高级」里的「拉取镜像」。 - 多机部署 / 上架官方商店时镜像必须公开可拉:推到自己的仓库后同步改 compose 里的
image:。
首次启动日志长什么样
[entry] MySQL=mysql:3306/wujies_k3m8pq Redis=redis:6379 RabbitMQ=rabbitmq:5672
[entry] 等待 MySQL 就绪…
[entry] 首次启动:初始化数据库 wujies_k3m8pq
[entry] 导入 01-platform.sql
[entry] 导入 02-app-market.sql
[entry] 导入 03-app-catalog.sql
[entry] 应用目录:app_info=18 行 app_version=12 行
[entry] 数据库初始化完成,已写入标记 platform.init.version=5.6.3
[entry] 启动应用(profile=prod)第二次启动看到的是 数据库已初始化过(platform.init.version=…),跳过导入。库名 / 账号是表单随机生成的(形如 wujies_<6位随机>),所以日志里不是 wujies。
首次启动的初始化逻辑
初始化由 deploy/docker/backend/entrypoint.sh 负责(中间件不随包安装,拿不到 MySQL 容器的 docker-entrypoint-initdb.d 时机),顺序固定:
| 顺序 | 文件 | 内容 |
|---|---|---|
| 1 | 01-platform.sql | 平台初始化:平台表 + 平台数据(地区 / 字典 / 参数 / 菜单),源头 script/sql/platform_init.sql |
| 2 | 02-app-market.sql | 应用市场自己的表与列(由 build-1panel.ps1 把 script/sql/update/ 下的 7 个脚本拼成一份) |
| 3 | 03-app-catalog.sql | 应用目录种子(app_info + app_version,从发布方库导出,源头 script/sql/app_catalog_seed.sql) |
导入用 mysql --force(容忍个别语句报错),随后做两道复核,任一不过就让容器失败并不写标记:
- 关键表全检(19 张):
sys_user、sys_role、sys_menu、sys_dept、sys_post、sys_config、sys_dict_type、sys_dict_data、sys_area、sys_oss_config、sys_tenant、sys_user_todo、app_info、app_version、app_category、app_install、app_install_task、app_version_menu、app_schema_history。宁可安装当场失败,也不要交付一个残库。 - 目录数据非空复核:存在
03-app-catalog.sql时校验app_info≥ 1 行。表在 ≠ 数据在,一个字符集错误就会让目录整段静默失败,交付出去就是「装成功了、市场里一个应用都没有」。
判据是 sys_config 里的标记行 platform.init.version——不是「有没有 sys_user 表」:半途失败的库会缺表但已有表,用表存在与否判断会失真。
compose 里是 - ./sql:/app/sql:ro,所以改 SQL 不用重建镜像,换文件即可:已安装实例用它自己那份(/opt/1panel/apps/<应用>/<实例名>/sql/files/),资源目录那份只给以后的新安装用。只有改了 jar 或前端 dist/ 才要 docker build。
让已经装过的实例用上新的初始化 SQL
entrypoint 只在第一次启动(没有标记行)时导入,所以换完文件还要让它重跑一次:
| 改的是 | 做法 |
|---|---|
| 只改数据(种子数据 / 字典 / 参数 / 地区 / 应用目录) | 删标记行 + 重启(脚本幂等:CREATE TABLE IF NOT EXISTS + INSERT IGNORE / WHERE NOT EXISTS),库和表都不动 |
| 改了表结构(加列 / 改列 / 加索引) | IF NOT EXISTS 不改已有表 → 必须清空库里的表(不是删库)再重启 |
# 只改数据:删标记行再重启
docker exec <mysql容器> mysql -uroot -p<root密码> -e \
"delete from \`wujies_xxxxxx\`.sys_config where config_key='platform.init.version'"
docker restart <backend容器>面板建库时只给了 GRANT ALL PRIVILEGES ON \wujies_xxxxxx`.*,**没有全局 CREATE**。库一删,入口脚本那句 CREATE DATABASE IF NOT EXISTS` 就建不回来了,导入全落在不存在的库上,最后卡在「初始化不完整(缺 N 张关键表)」起不来。要重来请清空该库里的所有表(保留库与授权)再重启容器。
⚠️ 平台表结构的升级不随应用包走:库归你管,按发布说明执行 script/sql/update/ 下对应的脚本,见 /deploy/upgrade。
中间件:不在包里,怎么选 / 怎么填
MySQL、Redis、RabbitMQ 都不在应用包里,也不打进镜像。安装表单里每个中间件都是两条路:
| 中间件 | 必填 | 面板选服务 | 填外部 | 都空 |
|---|---|---|---|---|
| MySQL | 是 | 下拉选已装的 MySQL,面板据此建库 + 授权 | 填 EXTERNAL_DB_*,要自己先建库并授权 | 启动失败:没有数据库地址 |
| Redis | 是 | 下拉选已装的 Redis,面板带入 root 密码 | 填 EXTERNAL_REDIS_* | 启动失败:没有 Redis 地址 |
| RabbitMQ | 否 | 面板不会带入账号密码,默认按官方应用的 rabbitmq / rabbitmq 预填 | 填 EXTERNAL_RABBITMQ_* | 应用照常启动,只是消息中心 / 站内信不可用 |
解析规则是「外部字段非空 → 用外部;否则用面板选的服务;都空 → 启动失败并打印原因」,这段逻辑写在 entrypoint.sh 里——compose 与 Spring 都表达不了这种条件。数据库下拉只提供 MySQL:平台初始化 SQL 通篇 utf8mb4_0900_ai_ci,MariaDB 没有这个排序规则。
解析结果会被导出成 Spring 属性(环境变量优先级高于 jar 内 yml):
SPRING_DATASOURCE_DYNAMIC_DATASOURCE_MASTER_URL / _USERNAME / _PASSWORD
SPRING_DATA_REDIS_HOST / _PORT / _PASSWORD
SPRING_RABBITMQ_HOST / _PORT / _USERNAME / _PASSWORD定时任务调度中心与监控中心同理,留空 = 不启用:SNAIL_JOB_SERVER_HOST 非空才导出 SNAIL_JOB_ENABLED=true(不启用则订单自动取消 / 自动收货、优惠券状态与过期、促销启停、统计刷新、会员积分过期这些任务都不会跑,而且执行器已随各应用搬进插件);MONITOR_ADMIN_URL 非空才导出 SPRING_BOOT_ADMIN_CLIENT_ENABLED=true(否则监控中心里看不到这个实例,功能本身不受影响)。两者都填独立包的固定网络别名(snailjob-server / monitor-admin),不要填面板随机生成的容器名。
数据会落在应用目录里(卸载 / 迁移麻烦)、每个应用各跑一套中间件(内存翻倍)、版本与安全更新各自为政。复用面板的官方应用之后,中间件由面板统一升级与备份,应用只负责自己的库。
对象存储同理不在包里:装完在「系统工具 → 系统配置 → 文件存储配置」里启用一种(MinIO / 阿里云 / 腾讯云 / 七牛)。默认所有配置都是停用状态,所以刚装完上传会失败——这是刻意的。
五条必须遵守的纪律
1. build-1panel.ps1 必须保持 UTF-8 with BOM
Windows PowerShell 5.1 对没有 BOM 的脚本按 ANSI 解码,中文注释与字符串会被双重编码(典型报错是 Missing closing '}')。用编辑器改完确认前三字节是 EF BB BF。
2. *.sh 统一 LF
CRLF 的 shell 脚本在容器里报 bad interpreter。build-1panel.ps1 在拷 entrypoint.sh 时会做 \r\n → \n 归一化,但手工改过脚本再手工拷进容器就会绕过这一步。
3. 改版本号要同时动四处
| 位置 | 内容 |
|---|---|
deploy/tools/build-1panel.ps1 | $Version 默认值 |
| 包内目录名 | deploy/1panel/apps/<包>/5.6.x/ |
docker-compose.yml | 各处 image: 的 tag |
deploy/tools/gen-appstore-data.mjs | VERSION 常量 |
漏改任何一处,表现是「面板装的是新包、拉的是旧镜像」或「包版本目录与 compose 里的 tag 对不上」。
4. 不要在正在运行的 JVM 上跑 mvn install
运行中的 JVM 锁住了 wujies-admin.jar 与插件 jar,mvn install 会在写目标文件时失败(Windows 上尤其明显)。先停服务,或先只做 compile。
5. 插件目录在「-D 参数」与「yml / 环境变量」两处都要一致
容器里 entrypoint 用 -Dapp-market.deploy.plugin-dir="${PLUGIN_DIR:-/app/plugins-dist}" 传插件目录(启动器在 Spring 之前跑,只认系统属性),compose 又用 APP_MARKET_DEPLOY_PLUGIN_DIR 设了同名 Spring 属性。改插件目录要两处一起改,并且与宿主启动参数 -Dloader.path 指向同一个目录。
相关阅读
- /deploy/index —— 三种部署方式对比、四类产物、上线前脱敏清单
- /deploy/configuration ——
app-market:与security配置项逐条说明 - /deploy/frontend —— 前端构建模式与 nginx
/remote-apps/的四路径对齐 - /deploy/upgrade —— 平台表结构升级、应用升级与补数据脚本
- /deploy/multi-deployment —— 多套部署与目录集中
- /advanced/plugin-runtime —— 两套加载机制、
active-plugins.txt与产物回收 - /package/build —— 业务应用包(插件)怎么打
- /ops/troubleshooting —— 启动失败与接口报错的排查路径