安装模块
受众:开发者 摘要:企业安装向导:安装状态 / 令牌校验 / 环境预检 / 根路径接管 / 完整安装执行 / 安装锁定。
Install 模块提供企业级安装向导入口,用于私有化交付、Docker 部署和首次初始化检查。
当前已经提供安装状态 API、根路径接管、可选令牌校验、基础环境预检、配置校验 / 预览 / 写入、数据库迁移状态检测、IAM 基础数据确认、首个超级管理员创建、安装锁定、一键执行安装、会话日志、安装诊断、后台运维只读入口、受控安装状态重置和独立安装视图。
模块定位
后端模块:
<dependency>
<groupId>com.springopen</groupId>
<artifactId>spring-open-module-install</artifactId>
</dependency>API 前缀:
/api/v1/install/**安装页面入口:
/install/安装视图源码和构建模块:
views/install
spring-open-views/spring-open-view-install安装模块是可选业务模块。项目不需要安装向导时,可以从应用模块中移除该 Maven 依赖;其他业务模块不应该反向依赖安装模块。
配置
spring:
open:
install:
enabled: true
mode: auto
config-file: .env
execution-log-file: ${SPRING_OPEN_INSTALL_EXECUTION_LOG_FILE:${APP_STORAGE_DIR:${user.dir}/storage}/install/execution.log}
allow-reinstall: false
token: ${SPRING_OPEN_INSTALL_TOKEN:}
token-ttl: 30m
cidr-check-enabled: false
allowed-cidrs:
- "127.0.0.1/32"
- "::1/128"
require-https: false
allow-lite: true
access-protection-enabled: false
page:
enabled: true
root-route:
enabled: true
mode: redirect
target: /install/配置说明:
| 配置项 | 默认值 | 说明 |
|---|---|---|
spring.open.install.enabled | true | 是否启用安装向导和安装流程;关闭后后台演示数据清理仍由独立开关控制 |
spring.open.install.quickstart-cleanup.enabled | true | 是否启用后台演示数据清理 |
spring.open.install.mode | auto | 安装模式:auto、forced、disabled |
spring.open.install.config-file | .env | 安装向导写入的本地配置文件 |
spring.open.install.execution-log-file | ${APP_STORAGE_DIR:${user.dir}/storage}/install/execution.log | 安装执行日志文件;数据库可用时会同时写入并优先读取安装会话和步骤日志表 |
spring.open.install.allow-reinstall | false | 是否允许已安装后重新安装 |
spring.open.install.token | 空 | 安装令牌。非生产环境可留空以便开发;prod profile 默认开启生产门禁,安装入口开启时必须通过 SPRING_OPEN_INSTALL_TOKEN 提供高强度令牌 |
spring.open.install.token-ttl | 30m | 令牌校验后的建议有效期 |
spring.open.install.cidr-check-enabled | false | 是否启用安装入口来源网段校验;默认关闭,避免本地和内网部署被误拦截 |
spring.open.install.allowed-cidrs | 127.0.0.1/32、::1/128 | CIDR 校验启用后允许访问安装流程的网段 |
spring.open.install.require-https | false | 是否要求安装入口必须通过 HTTPS |
spring.open.install.allow-lite | true | 是否允许 lite 模式参与安装向导 |
spring.open.install.access-protection-enabled | false | 未安装时是否阻止访问非安装入口;默认关闭,避免所有请求默认经过安装状态检查;只在引用 Install 模块且安装模块启用时生效 |
spring.open.install.page.enabled | true | 是否启用内置安装页骨架 |
spring.open.install.root-route.enabled | true | 未安装时是否接管根路径 |
spring.open.install.root-route.mode | redirect | 根路径接管模式:forward 或 redirect;安装视图默认使用 redirect,避免根路径下相对静态资源加载错误 |
spring.open.install.root-route.target | /install/ | 未安装时根路径目标 |
上述安装模块启停、安装模式、令牌、重装、访问保护、内置安装页和根路径接管配置已由 InstallServiceProvider 声明到 lifecycle 配置 schema;后台配置中心可发现这些安装交付主干配置,spring.open.install.token 会标记为敏感配置。
分布式部署下不能依赖单机文件判断安装状态。运行期统一通过配置门面读取 spring.open.install.installed,Config database provider 下由 config_entry 承载,所有实例共享同一状态;install_state 只保留兼容与审计用途,不作为前端或其他模块的直接判断来源。
未安装访问保护是可选能力,默认不开启,避免每个请求都经过安装状态判断。显式设置 access-protection-enabled=true 时,Install 模块会在模块内部拦截非安装入口访问:/install/** 和 /api/v1/install/** 正常放行;/admin/、/app/、/pc/、/docs/ 等页面请求会重定向到 /install/;非安装 API 和 WebSocket 请求返回 JSON 503,避免浏览器页面拿到被统一响应包装过的 HTML。该能力只属于 Install 模块,移除或禁用 Install 模块后不会影响其他业务模块。
安装完成且 allow-reinstall=false 时,/install 和 /install/ 会直接回到状态快照里的 productPath 产品入口,不再展示安装向导;带 context path 部署时后端会按当前请求前缀拼接为站内相对路径,异常的协议相对路径会退回根路径,避免安装页成为外部跳转入口。Docker / Nginx 静态优先部署下,安装视图自身也会在状态接口确认已安装后回到产品入口。
安装完成页会提供后台管理、移动端 H5、PC 端、WebSocket 聊天体验和安装文档入口,全部使用相对路径,适配 context path、Docker / Nginx 子路径和本地静态部署。若 public/install/index.html 未构建,后端兜底安装页仍会展示状态 API 与安装文档链接,便于部署方先排查视图构建或静态资源路径问题。
状态 API
GET /api/v1/install/status返回示例:
{
"code": "200",
"message": "OK",
"data": {
"enabled": true,
"mode": "auto",
"installed": false,
"installAllowed": true,
"allowReinstall": false,
"locked": false,
"installPath": "/install/",
"productPath": "/",
"rootRouteMode": "redirect",
"rootRouteTarget": "/install/",
"snapshotAt": "2026-06-06T08:21:55Z"
}
}字段说明:
| 字段 | 说明 |
|---|---|
installed | 当前是否已经安装;以 Config 门面读取的 spring.open.install.installed 为权威,适配多实例 / 分布式部署 |
installAllowed | 当前是否允许进入安装流程 |
allowReinstall | 是否开启 spring.open.install.allow-reinstall;后台安装状态重置入口据此判断是否可用 |
locked | 是否因安装锁定而不可继续安装 |
installPath | 安装页面入口 |
productPath | 安装完成后可恢复访问的产品入口;带 context path 的部署由页面或调用方按当前请求前缀拼接 |
snapshotAt | 服务端生成该状态快照的时间,用于安装页和运维页判断状态是否新鲜 |
后台运维 API
安装向导入口使用 /api/v1/install/**,安装前主要依赖可选安装令牌保护。安装完成后,后台管理界面使用 /api/v1/admin/install/** 查询安装状态、步骤、会话和日志,不再依赖安装令牌。
后台只读运维接口统一要求权限 install:view;敏感运维动作(写)要求 install:manage。
只读运维入口:
| 接口 | 权限 | 说明 |
|---|---|---|
GET /api/v1/admin/install/diagnostics | install:view | 聚合查询安装诊断信息 |
GET /api/v1/admin/install/diagnostics/export | install:view | 下载安装诊断 JSON 文件 |
GET /api/v1/admin/install/status | install:view | 查询安装状态 |
GET /api/v1/admin/install/steps | install:view | 查询安装步骤计划 |
GET /api/v1/admin/install/sessions | install:view | 分页查询安装执行会话,支持 status、keyword、page、size |
GET /api/v1/admin/install/sessions/{sessionId} | install:view | 查询安装会话和步骤日志,支持 limit |
GET /api/v1/admin/install/sessions/{sessionId}/export | install:view | 下载安装会话和步骤日志 JSON 文件,支持 limit |
GET /api/v1/admin/install/execution-logs | install:view | 查询最近安装执行记录,支持 limit |
GET /api/v1/admin/install/audit-logs | install:view | 分页查询安装审计日志,支持 action、status、keyword、page、size |
敏感运维动作:
| 接口 | 权限 | 说明 |
|---|---|---|
POST /api/v1/admin/install/state/reset | install:manage | 受控重置安装状态,把已安装系统退回未安装以便重装 |
POST /api/v1/admin/install/state/mark-installed | install:manage | 受控标记为已安装,把未安装系统补锁为已安装 |
POST /api/v1/admin/install/migrate | install:manage | 强制执行数据库迁移,对当前数据源运行 Liquibase(幂等) |
演示数据清理
演示数据清理入口由 Install 模块聚合,但仍沿用 Install 运维路由和权限,方便后台统一治理内置演示数据。业务模块只实现 Core Runtime 的清理贡献方,Install 负责聚合预览、确认字段校验、执行和审计,业务模块之间不建立 Maven 依赖。
| 接口 | 权限 | 说明 |
|---|---|---|
GET /api/v1/admin/install/quickstart-cleanups | install:quickstart-cleanup:view | 查询所有已接入模块的清理预览 |
GET /api/v1/admin/install/quickstart-cleanups/{moduleCode} | install:quickstart-cleanup:view | 查询指定模块的目标、阻塞项和确认字段 |
POST /api/v1/admin/install/quickstart-cleanups | install:quickstart-cleanup:execute | 一键清理所有当前可执行模块的演示数据;存在阻塞项的模块保持原状态 |
POST /api/v1/admin/install/quickstart-cleanups/{moduleCode} | install:quickstart-cleanup:execute | 执行指定模块清理,请求体必须原样提交模块编码、数据类型和确认短语 |
当前 CMS、Blog、Forum、Mall、Advertising、AI、Chat、Distribution、Form、Live、Live Code、Marketing、Marketplace、Meeting、Open Platform、Payment Platform、Reading、Short Link 和 Video 已接入演示数据清理贡献方。执行成功或失败都会写入 install_audit_log,action=quickstart-cleanup;审计消息只记录模块、清理类型、目标 / 阻塞数量和错误 key,不记录确认短语,避免把高危确认文本当成操作凭据长期保存。一键清理需要提交确认短语 一键清理演示数据,后端只会执行 executable=true 的模块,阻塞和无目标模块只返回当前预览状态,不做强制删除;删除 SQL、外键约束或数据源异常会按失败返回并回滚,清理成功后仍检测到目标数据残留时也视为失败。
安装状态重置
重置安装状态会重新开放安装入口,属于高危运维动作,要求三重确认才执行:
- 权限:
install:manage - 配置闸门:
spring.open.install.allow-reinstall=true(默认false,生产默认关闭) - 显式确认短语:请求体
confirmation必须等于RESET-INSTALL
POST /api/v1/admin/install/state/reset
Content-Type: application/json
{
"confirmation": "RESET-INSTALL",
"reason": "重新部署到新数据库"
}| 字段 | 必填 | 说明 |
|---|---|---|
confirmation | 是 | 确认短语,必须为 RESET-INSTALL(大小写和首尾空白会归一) |
reason | 否 | 重置原因,写入审计日志,最多保留 200 字符 |
行为:
- 三重确认任一不满足 → 返回
reset=false拒绝结果,不修改安装状态 - 系统本就未安装 → 幂等返回
reset=true+alreadyUninstalled=true - 确认通过且已安装 → 写
spring.open.install.installed=false,同步install_state兼容状态,安装入口重新开放 - 每次调用写
install_audit_log,action=state-reset,记录 status、操作人 IP、User-Agent、traceId 和脱敏摘要
标记为已安装
标记为已安装是重置的反向操作,把未安装系统补标记为已安装,适用于系统实际已配置好但安装标记缺失(如恢复备份、迁移环境后运行时配置缺失)导致安装器误重开的恢复场景。要求权限 install:manage 和显式确认短语 MARK-INSTALLED。
POST /api/v1/admin/install/state/mark-installed
Content-Type: application/json
{
"confirmation": "MARK-INSTALLED",
"reason": "恢复备份后补标记"
}| 字段 | 必填 | 说明 |
|---|---|---|
confirmation | 是 | 确认短语,必须为 MARK-INSTALLED(大小写和首尾空白会归一) |
reason | 否 | 标记原因,写入审计日志,最多保留 200 字符 |
行为:
- 确认短语不匹配 → 返回
marked=false拒绝结果,不修改安装状态 - 系统本就已安装 → 幂等返回
marked=true+alreadyInstalled=true - 确认通过且未安装 → 写
spring.open.install.installed=true,同步install_state兼容状态,安装入口锁定 - 每次调用写
install_audit_log,action=state-mark-installed,记录 status、操作人 IP、User-Agent、traceId 和脱敏摘要
安装状态的其余敏感动作沿用同一「权限 + 显式确认 + 审计 + 幂等」模式。
数据库迁移
数据库迁移默认在应用启动阶段由 Liquibase 自动执行。安装过程和运维场景也可以按需显式触发,对当前数据源运行 Liquibase update,幂等只应用待执行的变更集:
| 接口 | 鉴权 | 用途 |
|---|---|---|
POST /api/v1/install/migrate | 安装令牌 | 安装向导「安装过程」步骤显式导入数据库表结构和种子数据 |
POST /api/v1/admin/install/migrate | install:manage | 部署新版本后由后台手动补迁移 |
POST /api/v1/admin/install/migrate返回字段:
| 字段 | 说明 |
|---|---|
migrated | 迁移是否成功 |
pendingBefore | 执行前待执行的变更集数量 |
applied | 本次实际应用的变更集数量 |
upToDate | 是否已是最新(无待执行变更) |
message | 结果说明 |
行为:
- 幂等:无待执行变更集时返回
upToDate=true,不重复执行 - 对当前运行中的数据源执行;修改数据库连接指向新库的场景仍需重启,由启动阶段对新库迁移(运行中的 JVM 不会热切换数据源)
- 失败时返回
migrated=false和脱敏错误说明;安装流程中迁移失败会停止后续步骤
后台「安装运维」控制台(安装运维)已把上述只读查询和敏感运维动作接出为可视化页面:状态卡、执行会话和审计日志只读表、危险区包含重置安装状态、标记为已安装和执行数据库迁移三个按钮。重置和标记使用短语强确认弹窗;数据库迁移使用二次确认弹窗,并提示只作用于当前运行数据源。
安装诊断
GET /api/v1/admin/install/diagnostics诊断接口用于后台部署排障,一次返回当前安装状态、步骤计划、环境预检结果、最近安装会话和最近执行日志。该接口只读,不执行数据库迁移、不写配置、不创建管理员、不修改安装状态。
如需远程协助,可下载同一份脱敏诊断包:
GET /api/v1/admin/install/diagnostics/export导出内容为 JSON 文件,使用相同的 install:view 权限,适合发送给部署或运维人员排查问题。诊断包不包含安装令牌、管理员密码、数据库密码或 Redis 密码。
如需只导出某一次安装执行,可下载会话包:
GET /api/v1/admin/install/sessions/{sessionId}/export?limit=500会话包包含该安装会话摘要和步骤日志,适合保留某次失败或重试的现场记录。
典型用途:
- 后台安装运维页面首屏聚合展示。
- 部署人员快速判断是环境预检、数据库迁移、IAM 基础数据还是执行日志异常。
- 给远程协助人员复制诊断摘要,避免反复调用多个接口。
- 下载 JSON 诊断包,用于保留现场排障快照。
令牌校验
POST /api/v1/install/token/verify
Content-Type: application/json
{
"token": ""
}默认情况下 spring.open.install.token 为空,表示安装入口不要求输入令牌,直接提交空令牌即可继续安装流程。生产交付或公网可访问部署时,建议通过环境变量启用令牌保护:
SPRING_OPEN_INSTALL_TOKEN=replace-with-high-entropy-install-token启用令牌后,令牌校验接口通过请求体传入令牌;后续预检、配置写入、一键安装、管理员创建和锁定等受保护接口通过 X-Install-Token 请求头传入令牌:
X-Install-Token: replace-with-high-entropy-install-token返回字段:
| 字段 | 说明 |
|---|---|
valid | 安装入口校验是否通过 |
tokenConfigured | 后端是否已经配置安装令牌 |
installed | 当前是否已安装 |
installAllowed | 当前是否允许继续安装 |
reason | 结果原因编码,例如 install.token.not-required、install.token.valid、install.token.invalid、install.token.not-allowed |
expiresAt | 建议过期时间;未配置令牌时为空 |
配置默认值
GET /api/v1/install/config/defaults
X-Install-Token: change-me配置默认值接口会基于当前 Spring Boot 运行配置生成安装表单默认值,例如站点名称、数据库 URL、数据库用户名、数据库密码、Redis 主机、Redis 密码和 Storage disk。Docker 一体化镜像中,DB_PASSWORD 已由运行脚本注入,安装视图会在入口校验通过后自动填入数据库密码,避免部署人员手动猜测默认密码。
该接口必须先通过安装入口校验。未配置安装令牌时可直接使用空令牌;配置令牌后必须传入 X-Install-Token。数据库密码、Redis 密码等敏感默认值只用于未安装流程的表单预填,不写入本地存储,不出现在状态接口、诊断摘要或执行日志中。
配置字段 Schema
GET /api/v1/install/config/schema配置字段 Schema 接口返回安装表单字段元数据,包括站点、管理员、数据库、Redis 和 Storage 分组下的字段标签、说明、必填标记、候选项和渲染提示。安装视图用该 contract 驱动字段展示,避免前端重复维护动态表单字段定义。
该接口只返回字段定义,不返回配置值、数据库密码、Redis 密码或管理员密码。需要预填运行时默认值时继续使用 GET /api/v1/install/config/defaults,需要真正写入配置时继续走配置校验、写入预览和写入接口。
环境预检
POST /api/v1/install/preflight
X-Install-Token: change-meX-Install-Token 只有在后端配置了 spring.open.install.token 时才需要传入;默认空令牌部署可以不传该请求头。 当前预检只做低风险检查,不执行数据库迁移、不写入 .env、不创建管理员。
预检项包括:
- Java 版本。
- 默认字符集。
- JVM 最大堆内存。
- 运行目录、
storage、public、运行日志目录。 - 数据库连接:已配置
DataSource时尝试连接并读取数据库产品信息;未检测到DataSource时给出warning,不直接阻塞轻量安装页。 - Redis 连接:已配置
RedisConnectionFactory时尝试读取服务器时间;未检测到 Redis Bean 时给出warning。 - Storage 服务:检测
StorageManager以及默认public/localdisk 是否可用。 - 数据库迁移状态:检测 Liquibase changelog 表、迁移记录数量和 changelog lock 锁状态,帮助判断当前数据库是否已经经过迁移,以及是否存在未释放的迁移锁。
- HTTPS 策略。
- lite 模式策略。
返回字段:
| 字段 | 说明 |
|---|---|
authorized | 是否通过安装入口校验 |
passed | 是否没有失败项;warning 不阻塞 |
checks[].status | passed、warning、failed |
checks[].message | 当前检查说明 |
配置校验
POST /api/v1/install/config/validate
X-Install-Token: change-me
Content-Type: application/json
{
"site": {
"name": "My App",
"title": "My App",
"url": "https://example.com",
"defaultLocale": "zh-CN",
"timeZone": "Asia/Shanghai"
},
"administrator": {
"username": "admin",
"email": "admin@example.com",
"mobile": "",
"password": "123456",
"confirmPassword": "123456"
},
"database": {
"type": "mysql",
"host": "127.0.0.1",
"port": 3306,
"database": "spring_open",
"username": "spring_open",
"password": "secret"
},
"redis": {
"enabled": true,
"host": "127.0.0.1",
"port": 6379,
"database": 0,
"password": ""
},
"storage": {
"publicDisk": "public",
"localDisk": "local"
}
}配置校验只判断表单语义,不写入配置、不执行迁移、不创建管理员。
当前校验项包括:
- 站点名称、站点 URL、默认语言、默认时区。
- 首个超级管理员用户名、邮箱 / 手机建议项、密码策略和确认密码。默认密码策略为 low:最少 6 位并允许简单弱口令;生产环境可在系统密码策略中切换为 medium、high 或 custom。
- 数据库类型和必填字段,支持
mysql、postgresql、h2;生产建议使用 MySQL 或 PostgreSQL。 - Redis 启用后的主机和端口。
- 公共 / 私有文件存储 disk。
返回结构和预检一致,warning 用于提示风险或缺省值,failed 表示安装执行前必须处理。
配置写入预览
POST /api/v1/install/config/plan
X-Install-Token: change-me
Content-Type: application/json
{
"site": {
"name": "My App",
"title": "My App",
"url": "https://example.com",
"defaultLocale": "zh-CN",
"timeZone": "Asia/Shanghai"
},
"administrator": {
"username": "admin",
"email": "admin@example.com",
"mobile": "",
"password": "strong-password",
"confirmPassword": "strong-password"
},
"database": {
"type": "mysql",
"host": "127.0.0.1",
"port": 3306,
"database": "spring_open",
"username": "spring_open",
"password": "secret"
},
"redis": {
"enabled": true,
"host": "127.0.0.1",
"port": 6379,
"database": 0,
"password": ""
},
"storage": {
"publicDisk": "public",
"localDisk": "local"
}
}配置写入预览会先复用配置校验结果。只有没有 failed 项时,才返回 entries;如果校验失败,entries 为空。
返回字段:
| 字段 | 说明 |
|---|---|
authorized | 是否通过安装入口校验 |
passed | 配置校验是否通过 |
checks[] | 配置校验项,结构和配置校验接口一致 |
entries[].propertyKey | Spring 配置 key |
entries[].environmentKey | 对应环境变量 key;数据库配置和运行时专用字段可能为空 |
entries[].maskedValue | 脱敏后的配置值 |
entries[].sensitive | 是否敏感配置 |
entries[].target | 计划写入目标,例如 .env、config 或 runtime |
entries[].note | 配置说明 |
这个接口只用于安装执行前确认配置计划,不写入 .env 或数据库配置,不执行 Liquibase 迁移,也不创建管理员。 数据库密码、Redis 密码和管理员密码只返回固定脱敏值,不回显明文或前后字符。
写入安装配置
POST /api/v1/install/config/write
X-Install-Token: change-me
Content-Type: application/json请求体和配置校验一致。接口会先复用配置校验和写入计划;校验通过后,按配置类型分别写入项目根目录 .env 和数据库配置。
当前写入规则:
.env只写入.env.example中出现过的环境变量 key,例如数据库、Redis 等启动配置;不在.env.example白名单里的 key 不由安装器写入。- 站点名称、站点标题、站点 URL、站点默认时区、Storage 默认 disk 和 disk 启用状态写入数据库配置,便于运行期通过 Config 门面读取。
- 进程 / 启动前才能生效的配置不写入数据库配置;当前安装器不会把
spring.liquibase.enabled、user.timezone或默认语言等不具备运行期 Config 消费的配置写入数据库。 - 已存在的同名环境变量会被更新,其他内容和注释保留;如果原行使用
export KEY=...,安装器会保留export前缀,适配直接source .env的部署习惯。 - 数据库密码、Redis 密码等启动敏感值会按
.env.example白名单写入.env,但响应只返回固定脱敏值。 - 首个超级管理员密码属于安装执行期运行时数据,不写入
.env。 - 本接口只写安装配置,不执行 Liquibase、不创建管理员、不写安装锁。
修改数据库连接后需要重启应用,让 .env 由 Spring Boot 重新加载,并由启动阶段 Liquibase 迁移目标数据库。
一键执行安装
POST /api/v1/install/execute
X-Install-Token: change-me
Content-Type: application/json请求体和配置校验一致。该接口用于安装页面的一键安装按钮,会按顺序执行:
- 环境预检。
- 配置校验。
- 写入
.env。 - 对当前运行数据源执行数据库迁移。
- 执行安装任务扩展点,当前内置“IAM 基础数据确认”任务;CMS、Blog、Forum、Mall 引入时会自动注册各自的数据库表就绪检查任务。
- 创建或确认首个超级管理员。
- 写入配置门面安装状态,并同步运维审计状态。
返回字段:
| 字段 | 说明 |
|---|---|
authorized | 是否通过安装入口校验 |
passed | 安装流程是否完成 |
restartRequired | 是否需要重启应用:仅当本次写入改变了数据库或 Redis 连接配置时为 true;未改连接(如同库重装、只填站点 + 管理员)时为 false,可直接使用 |
configWritten | .env 是否已写入 |
administratorReady | 超级管理员步骤是否就绪 |
locked | 安装入口是否已锁定 |
message | 结果说明 |
sessionId | 本次完整安装执行的会话 ID |
retriedSessionId | 如果本次执行来自失败会话重试,这里返回来源会话 ID |
records[] | 本次执行步骤日志 |
安装执行会在第一个失败步骤停止,并把步骤日志写入 spring.open.install.execution-log-file。
是否需要重启按实际连接变更判定,避免让不熟悉部署的用户做多余操作:
- 未改数据库 / Redis 连接(最常见:容器或部署时已配好库,向导只填站点 + 管理员;或重置后在原库重装)→
restartRequired=false,提示「可直接使用,无需重启」。安装流程会对当前运行数据源执行 Liquibase 迁移,迁移本身幂等,只应用待执行变更集;IAM 基础数据、管理员创建和安装锁定也按幂等规则处理。 - 改了数据库 / Redis 连接(指向新库)→
restartRequired=true。运行中的 JVM 不会自动切换数据源,.env已写入但需重启应用,让 Spring Boot 重新加载连接;重启后启动阶段会对新数据源执行 Liquibase 迁移,或由安装运维控制台对当前新数据源手动执行迁移。 失败后不保存敏感表单快照;安装视图会保留当前页面表单,调整配置后可再次点击“一键完成安装”,也可以从失败会话日志点击“按当前表单重试”。
重试某次失败会话:
POST /api/v1/install/sessions/{sessionId}/retry
X-Install-Token: change-me
Content-Type: application/json请求体和配置校验一致。重试接口不会读取或恢复旧会话里的敏感表单数据,只会在来源会话写入 retry-requested 记录,然后基于当前请求体发起一次新的完整安装执行,并返回新的 sessionId。
安装任务扩展点由 InstallTaskRegistry 和 InstallTaskExecutor 管理。可选模块如果需要参与安装,只注册自己的 InstallTask Bean;安装模块核心不硬编码依赖可选业务模块。
InstallTask 支持声明:
getCode():全局唯一的步骤编码。getOrder():基础排序,数值越小越靠前。getDependencies():前置步骤编码。依赖已注册任务时会自动排在依赖之后;依赖内置步骤时会保留给安装视图展示。isRequired():必需任务失败后停止安装;非必需任务失败后记录日志并继续。isRetryable():告诉安装视图该任务失败后是否适合重试。isCompleted():幂等检查,已完成时跳过执行。
安装成功后会发布 InstallCompletedEvent。该事件只包含会话 ID、完成时间、是否建议重启、日志数量和结果消息,不携带 .env、密码、密钥等敏感配置;应用装配层会把它接入 Notification 通知规则 install.execution.completed,运营可在通知规则中配置用户接收人、通道、去重和静默窗口。
安装失败后会发布 InstallExecutionFailedEvent。该事件只包含会话 ID、失败时间、失败步骤编码、步骤消息、失败步骤数、日志数量和结果消息;应用装配层会把它接入 Notification 通知规则 install.execution.failed,运营可在通知规则中配置用户接收人、通道、去重和静默窗口。
当前 core 公共层提供轻量的 DatabaseTablesInstallTask 样板,用于确认数据库表是否存在。业务模块默认不注册安装任务,也不依赖 spring-open-module-install;确有安装检查需求时,只能依赖 core 公共 InstallTask contract 提供 Bean,由安装模块在运行期收集执行。
这些任务只做只读检测,不创建表、不执行迁移、不写业务数据。业务模块需要更复杂的安装步骤时,优先通过 core 公共 contract 小步接入,继续保持安装模块核心不反向依赖可选业务模块。
创建超级管理员
直连创建接口由 /api/v1/install/ 和 administrator 两段路径组成,方法为 POST。
POST <install-administrator-path>
X-Install-Token: change-me
Content-Type: application/json
{
"username": "admin",
"email": "admin@example.com",
"mobile": "",
"password": "123456",
"confirmPassword": "123456"
}本接口用于首次安装创建超级管理员,并复用 IAM 模块的用户、角色和 RBAC 能力:
- 仅在安装入口校验通过时可调用;未配置令牌时不要求输入。
- 如果系统还没有用户,则创建用户并挂载内置
super-admin角色。 - 如果已检测到IAM 用户,则认为管理员创建步骤已经完成,便于安装流程恢复。
- 密码校验复用当前 IAM 密码策略;默认 low 策略为最少 6 位并允许简单弱口令,生产环境可切换为 medium、high 或 custom。
- 不写
.env,不回显密码,不自动登录。
返回字段:
| 字段 | 说明 |
|---|---|
authorized | 是否通过安装入口校验 |
ready | 管理员步骤是否就绪 |
created | 是否本次创建了用户 |
userId | 本次创建的用户 ID |
username | 本次创建的用户名 |
安装向导只负责创建首个受控超级管理员,不提供固定默认测试账号。普通用户账号应通过用户端注册、短信 / 邮箱验证码注册或外部身份登录创建;联调需要普通用户时,也应走用户侧流程,而不是在安装模块里生成固定账号。 | message | 结果说明 |
安装视图会在 .env 写入后显示“创建超级管理员”按钮。若修改了数据库连接,应先重启应用,再继续创建管理员和锁定安装入口。
锁定安装入口
POST /api/v1/install/lock
X-Install-Token: change-me本接口用于写入配置门面安装状态,让 /install/ 入口和安装写操作自动失效。运行期以 Config.get("spring.open.install.installed", Boolean.class, false) 为权威;install_state 只用于兼容与审计。它只负责锁定入口,不执行 Liquibase、不创建管理员。
返回字段:
| 字段 | 说明 |
|---|---|
authorized | 是否通过安装入口校验 |
locked | 是否已写入安装锁 |
lockedAt | 锁定时间 |
status | 锁定后的安装状态 |
安装视图会在超级管理员步骤就绪后显示“锁定安装入口”按钮。一键执行接口会在迁移确认、IAM 基础数据确认和管理员创建成功后自动调用同一锁定能力。
安装步骤
GET /api/v1/install/steps安装步骤由后端模块统一提供,安装视图只消费接口,不在前端硬编码流程。内置步骤和可选模块注册的安装任务会合并成同一份步骤计划。
返回字段:
| 字段 | 说明 |
|---|---|
steps[].sequence | 步骤序号 |
steps[].code | 步骤编码 |
steps[].name | 步骤名称 |
steps[].description | 步骤说明 |
steps[].status | 当前步骤状态,第一阶段为 pending 或 passed |
steps[].message | 状态说明 |
当前步骤包括:
- 安全入口。
- 环境预检。
- 配置校验。
- 配置写入。
- 数据库迁移。
- IAM 基础数据确认。
- 管理员创建。
- 安装锁定。
一键执行接口会把本次执行的 sessionId 和步骤日志接入这套步骤模型,便于失败后按会话排查。
执行日志
GET /api/v1/install/execution-logs?limit=100
X-Install-Token: change-me安装模块会把预检、配置校验、配置预览、配置写入、管理员创建和安装锁定等关键操作写入数据库执行日志和本地执行日志文件。默认文件路径:
${APP_STORAGE_DIR:${user.dir}/storage}/install/execution.log文件执行日志采用 JSON Lines 格式,便于部署人员排查安装过程。数据库可用时,安装会话和步骤日志会同步写入 install_session、install_step_log,执行日志查询优先读取数据库记录;数据库不可用或无记录时回退文件日志,用于兜底排障。
limit 用于限制最近记录数量,最大返回 500 条。和其他安装写操作一样,X-Install-Token 只有在后端配置了安装令牌时才需要传入。
查看某次完整安装执行的步骤日志:
GET /api/v1/install/sessions/{sessionId}?limit=100
X-Install-Token: change-mePOST /api/v1/install/execute 会返回 sessionId,安装视图也会在日志中显示它。单独的预检、配置预览、配置写入、管理员创建和锁定动作仍会写入最近日志,但不强制归属某个完整安装会话。 失败会话可以通过 POST /api/v1/install/sessions/{sessionId}/retry 基于当前表单重新执行;安装模块不会保存旧会话的数据库密码、管理员密码或其他敏感表单快照。
安装审计
安装模块会把安装入口校验、预检、配置校验、配置写入、一键执行、失败重试、管理员创建和安装锁定等关键动作写入数据库审计表:
install_audit_log审计记录只保存动作、状态、会话 ID、来源 IP、User-Agent、traceId 和脱敏摘要,不保存数据库密码、Redis 密码、管理员密码、AccessKey、SecretKey 或安装令牌。
后台可通过只读接口查询:
GET /api/v1/admin/install/audit-logs?page=1&size=20&action=execute&status=passed该接口要求后台登录态和 install:view 权限。
返回字段:
| 字段 | 说明 |
|---|---|
authorized | 是否通过安装入口校验 |
sessionId | 会话日志接口返回的安装会话 ID |
records[].id | 执行记录 ID |
records[].sessionId | 完整安装执行会话 ID;单步操作可能为空 |
records[].stepCode | 步骤编码 |
records[].status | 执行状态:passed、warning、failed |
records[].message | 执行说明 |
records[].occurredAt | 发生时间 |
根路径接管
Install 模块通过 View starter 的根路径扩展点接入。
当满足以下条件时,请求 / 会进入安装入口:
spring.open.view.root.enabled=truespring.open.install.enabled=truespring.open.install.root-route.enabled=true- 配置门面中的安装状态不是已安装
- 安装模式不是
disabled
安装完成后写入配置门面安装状态,根路径接管自动失效,/ 继续回到 View starter 配置的产品入口。
安装视图
第一阶段已经提供独立 Vue 3 + Vite 安装视图:
views/install它会构建到:
public/install当前页面按常规安装程序做成四步向导,顶部进度和安装状态常驻,每一步只展示当前需要的内容,不再把所有面板堆在一页:
- 环境检查:安装入口校验(默认无需令牌)+ 基础环境预检;预检通过后「下一步」按钮才可点。
- 配置填写:填写数据库、Redis、站点信息和管理员账号,点击「开始安装」触发校验并执行;可选「校验配置」「生成配置预览」。
- 安装过程:执行预检、写入配置、数据库迁移、系统数据、创建管理员和锁定,展示安装结果和步骤进度;失败可返回配置修改或重新安装。
- 完成:展示安装结果和后台、五端、文档等常用入口。
页面文案使用“安装控制台 / 安装向导”等中性表达,不使用偏宣传口径。未配置安装令牌时,页面不会展示“无需令牌”结果卡或内部原因编码;配置令牌后才提示输入和校验结果。执行日志、诊断摘要和日志 JSON 会展示中文步骤名称,内部步骤编码只作为接口字段保留,避免部署人员看到 environment-preflight 这类内部值。
安装视图使用 vue-i18n 做前端国际化,当前内置简体中文和英文。页面会优先读取用户在安装页右上角选择的语言;未选择时按浏览器语言识别;后端请求会带上 Accept-Language,便于安装 API 返回对应语言的业务消息。安装完成后的正式业务多语言仍以项目 Spring i18n 和数据库文案为准,安装页只负责首次安装流程本身的 UI 文案。
页面已经接入:
- 安装状态读取。
- 安装入口校验。默认无需输入令牌,配置令牌后才要求输入。
- 基础环境预检。
- 配置校验 API。
- 配置写入预览。
.env白名单配置和数据库配置写入。- 首个超级管理员创建。
- 安装入口锁定。
- 后端安装步骤计划展示。
- 一键安装执行。
- 安装会话日志查看。
- 安装执行日志查询。
- 诊断摘要复制。
- 当前日志 JSON 下载。
安装视图只把令牌保存在页面内存中,不写入 localStorage。未配置令牌时页面可以留空继续;配置令牌时刷新页面后需要重新输入。
页面展示时间统一使用本地友好的日期时间格式,例如 2026-05-27 23:49:13,不直接展示 ISO 时间戳。安装成功后会显示后台、移动端、PC 端和聊天入口;安装失败时保留当前表单,用户修正配置后可直接重试。
「数据库类型」是可输入的候选框,页面内置 mysql、postgresql、h2、mariadb、oracle、sqlserver、dm、kingbase 等常用候选,也允许直接输入后续扩展支持的数据库类型。当前安装模块后端稳定支持 mysql、postgresql、h2;其他类型需要后续补齐驱动、JDBC URL 生成和安装校验后再用于生产安装。
如果安装时选择 PostgreSQL,在「数据库」区域按下面填写:
| 字段 | 示例 | 说明 |
|---|---|---|
| 数据库类型 | postgresql | 固定填写 postgresql |
| 数据库主机 | 127.0.0.1 / postgres / 数据库内网域名 | 必须是应用运行环境可以访问到的地址;Docker Compose 内部通常填服务名 |
| 数据库端口 | 5432 | PostgreSQL 默认端口 |
| 数据库名 | spring_open | 需要提前存在,或由部署脚本提前创建 |
| 数据库用户 | spring_open | 建议使用业务专用账号 |
| 数据库密码 | 对应账号密码 | 安装预览和日志中会脱敏 |
安装模块会据此生成 jdbc:postgresql://<host>:<port>/<database>,并写入 PostgreSQL 驱动类 org.postgresql.Driver。如果本次安装改变了正在运行中的数据库或 Redis 连接,安装结果会提示需要重启应用;重启后 Spring Boot 使用新连接启动,Liquibase 会在新数据库上执行迁移。
“复制诊断摘要”会把当前安装状态、令牌配置状态、预检 / 配置校验失败项、当前会话和最近日志整理成纯文本,方便部署人员远程排障。摘要不包含管理员密码、数据库密码、Redis 密码或安装令牌。
“下载日志 JSON”会基于页面当前已经读取到的最近日志或会话日志生成本地 JSON 文件,不额外扩大安装前公开 API 面。
安装视图构建默认使用相对静态资源路径,避免部署到 /install/、/developer/install/ 或其他任意层级目录时资源路径失效。部署层必须把 /install 重定向到 /install/,否则浏览器会把 ./assets/*.js 解析成 /assets/*.js,资源未命中时可能拿到 HTML 并触发模块 MIME 类型错误。项目内置 Docker Nginx 和安装模块直连入口都已处理该重定向。
API 默认使用相对前缀 ../api/v1/install,适合 public/install 与后端 API 同站部署;如部署拓扑不同,可在页面加载前覆盖:
<script>
window.__INSTALL_API_BASE__ = "../api/v1/install";
</script>安装完成或状态接口确认已安装后,安装视图会展示后续体验入口:
- 后台管理:
../admin/ - 移动端 H5:
../app/ - PC 端:
../pc/
这些入口都使用相对路径,便于整站部署到 Nginx 任意目录层级。
只构建安装视图:
./mvnw -pl spring-open-views/spring-open-view-install package -DskipTests -DskipITs -Dbuild.skip.views=false发布或私有化交付前,可以先生成安装向导复验报告:
./scripts/release install-smoke该报告只读取安装模块测试和视图文件,不写配置、不连接数据库、不启动服务。维护者应按报告继续执行安装模块测试、安装视图构建、Docker 静态 smoke,并在隔离环境里用浏览器复验安装令牌、预检、配置校验、配置预览、写入、执行、重试、锁定、后台诊断、审计日志、强制迁移和演示数据清理等关键链路。
第一阶段内置安装页仍保留,用于没有构建 public/install 时确认安装模块已启用,并引导调用状态 API。
后续如果使用 views/install 构建完整 Vue 安装向导,可以关闭内置页:
spring:
open:
install:
page:
enabled: falsepublic/install 由 public/.gitignore 忽略,构建产物不提交 Git。部署时可由 View starter 的 SPA 入口或 Nginx 静态资源服务承载。
后续能力
V1.0 前继续增强:
- 数据库状态表已经落地:
install_state、install_session、install_step_log、install_audit_log。安装状态已改为配置门面权威读取,install_state保留运维审计兼容;后台运维只读入口已提供,后续继续补升级判断。 - 更完整的后台运维动作和高风险操作二次确认。
- 更多可选业务模块安装任务注册;当前 CMS、Blog、Forum、Mall 已提供数据库表就绪检查样板。
- 数据库、Redis、Storage 检查在安装视图中的表单化接入。