Deploy admin web with release bundle
Some checks failed
CI / verify (push) Has been cancelled

This commit is contained in:
kdletters
2026-05-01 17:56:16 +08:00
parent 8718472dbd
commit 443a7781e5
9 changed files with 189 additions and 51 deletions

View File

@@ -4,13 +4,13 @@
对应 PRD[后台管理独立前端工程 PRD](../prd/ADMIN_WEB_CONSOLE_PRD_2026-04-30.md)
落地状态:`2026-04-30` 已创建 `apps/admin-web` 独立前端工程包含登录、总览、API 调试、兑换码管理和注册邀请码管理首版页面;根工程已补 `admin-web:*` 转发脚本。
落地状态:`2026-04-30` 已创建 `apps/admin-web` 独立前端工程包含登录、总览、API 调试、兑换码管理和注册邀请码管理首版页面;根工程已补 `admin-web:*` 转发脚本。`2026-05-01` 起,根构建与 Ubuntu 发布包会同步构建后台前端,并在发布包 Web 网关中以同域 `/admin/` 暴露。
## 1. 结论
后台管理端采用独立前端工程,路径固定为 `apps/admin-web`。它只负责 UI 表现、输入采集、请求发起和结果渲染所有鉴权、聚合、写操作、SpacetimeDB 访问和业务校验继续收口在 `server-rs/crates/api-server`
本方案接管旧 `api-server` 内嵌 HTML/CSS/JS 页面,旧 `GET /admin` 不再挂载。后续后台入口由独立前端工程部署产物承接
本方案接管旧 `api-server` 内嵌 HTML/CSS/JS 页面,Rust `api-server` 直连时`GET /admin` 不再挂载。部署态后台入口由发布包内 `web-server.mjs` 承接:`/admin/` 返回独立前端静态产物,`/admin/api/*` 继续反代到 `api-server`
## 2. 工程结构
@@ -384,12 +384,14 @@ export interface ProfileInviteCodeAdminResponse {
### 7.2 构建部署
首版构建产物由独立后台工程输出到 `apps/admin-web/dist`。部署可以选择
当前发布形态固定为同域 `/admin/`
1. 独立静态站点域名,例如 `https://admin.example.com`
2. 与主站同域不同路径,由网关把后台静态资源和 `/admin/api/*` 分别路由到正确目标
1. 本地单独执行 `npm run admin-web:build` 时,后台构建产物默认输出到 `apps/admin-web/dist`
2. 根工程执行 `npm run build` 时,会先构建主前端,再构建后台前端;任一构建失败或输出 warning 都会让构建门禁失败
3. Ubuntu 发布包执行 `npm run deploy:rust:remote` 时,后台前端以 Vite `--base /admin/` 构建到发布包 `web/admin/`
4. 发布包 `web-server.mjs``/admin` 返回 301 到 `/admin/`,对 `/admin/``/admin/*` 提供后台 SPA fallback`/admin/api/*` 优先反代到 `api-server`
无论哪种方式,`server-rs` 仍然是唯一管理 API 后端。
该形态不新增后台静态端口和后台专用后端。`server-rs` 仍然是唯一管理 API 后端,后台前端不直连 SpacetimeDB
### 7.3 后台工程脚本
@@ -399,8 +401,8 @@ export interface ProfileInviteCodeAdminResponse {
{
"scripts": {
"dev": "vite --host 127.0.0.1",
"build": "tsc --noEmit && vite build",
"typecheck": "tsc --noEmit",
"build": "node ../../scripts/admin-web-build.mjs build",
"typecheck": "node ../../scripts/admin-web-build.mjs typecheck",
"preview": "vite preview --host 127.0.0.1"
}
}
@@ -408,6 +410,8 @@ export interface ProfileInviteCodeAdminResponse {
如果后续接入根 npm workspace再在根 `package.json` 增加转发脚本;本轮不要为了后台工程强行重排现有前端脚本。
当前工程没有启用 npm workspace因此后台构建脚本必须从仓库根目录调用 root toolchain。`scripts/admin-web-build.mjs` 统一执行 `tsc --noEmit -p apps/admin-web/tsconfig.json` 与 Vite 构建,避免 `npm --prefix apps/admin-web` 在子目录找不到 `tsc`
当前根工程同步提供以下转发脚本:
1. `npm run admin-web:dev`

View File

@@ -137,11 +137,11 @@ npm run deploy:rust:remote
1. 在仓库根目录创建 `build/`
2.`build/` 下创建当前时间命名的目标目录,例如 `build/20260422-153000/`
3. 使用 Vite 构建前端 release 到目标目录的 `web/`
3. 使用 Vite 构建前端 release 到目标目录的 `web/`,并构建后台管理前端 release 到 `web/admin/`;后台构建固定使用 `/admin/` 作为 Vite base
4. 执行 `cargo build -p api-server --release --target x86_64-unknown-linux-gnu --manifest-path server-rs/Cargo.toml`,并把 `api-server` 复制到目标目录。
5. 执行 `cargo build -p spacetime-module --release --target wasm32-unknown-unknown --manifest-path server-rs/Cargo.toml`,并把 `spacetime_module.wasm` 复制到目标目录。
6. 把仓库根目录的 `.env``.env.local` 分别复制到目标目录根部和目标目录的 `web/` 下;复制后统一移除 UTF-8 BOM 与 CRLF并把 `GENARRATIVE_SPACETIME_DATABASE` 覆盖为本次 `--database` 参数,避免 Jenkins 工作区里残留的旧 `.env.local` 覆盖发布包目标库。
7. 在目标目录写入 `web-server.mjs`,用于托管 `web/` 并把 `/api/*``/generated-*``/healthz` 反代到本包内的 `api-server`
7. 在目标目录写入 `web-server.mjs`,用于托管 `web/` `web/admin/`;其中 `/admin` 跳转到 `/admin/``/admin/` 提供后台 SPA`/admin/api/*``/api/*``/generated-*``/healthz` 反代到本包内的 `api-server`
8. 在目标目录写入 `start.sh``stop.sh``start.sh` 会先按 `KEY=value` 子集加载发布目录根部的 `.env``.env.local`,兼容 UTF-8 BOM 与 CRLF再回退到构建时通过 `--database``--api-port``--web-host``--web-port``--spacetime-host``--spacetime-port` 写入的默认值,其中 Web 默认只监听 `127.0.0.1`;并默认导出 `NO_COLOR=1``CARGO_TERM_COLOR=never`,避免 ANSI 控制码写入日志文件;同时按 Ubuntu 发布环境使用发布目录内 `.spacetimedb/` 作为 root-dir不再额外设置 `--data-dir`,启动前先执行 `sync_ubuntu_spacetime_install`,优先从 `/usr/.local/share/spacetime/bin/<version>/spacetimedb-cli``$HOME/.local/share/spacetime/bin/<version>/spacetimedb-cli` 同步到 `.spacetimedb/bin/current/spacetimedb-cli`,当前线上 `spacetime` 入口为 `/usr/local/bin/spacetime`;启动参数为 `spacetime --root-dir ./.spacetimedb start --edition standalone --listen-addr <host>:<port>`,探活必须确认 `server ping` 输出包含 `Server is online:`;普通启动先无清库发布,若 publish 输出可判定为 schema 冲突,则自动导出旧库、清库发布新 wasm、导入回灌如果以 `--clear-database` 启动,则内部 `spacetime publish` 会追加 `-c=on-conflict`,代表人工确认清库,不触发自动回灌。
9. 默认执行 `scp -r -i ~\.ssh\dsk.pem build/<timestamp> ubuntu@82.157.175.59:/home/ubuntu/genarrative/` 上传发布包。
@@ -157,7 +157,9 @@ build/<timestamp>/
├─ .env.local
├─ web/
│ ├─ .env
─ .env.local
─ .env.local
│ └─ admin/
│ └─ index.html
├─ api-server
├─ spacetime_module.wasm
├─ migration-bootstrap-secret.txt
@@ -178,6 +180,8 @@ npm run build:rust:ubuntu -- --database genarrative-dev --web-host 127.0.0.1 --w
npm run build:rust:ubuntu -- --skip-upload
```
`--skip-web-build` 会同时跳过主前端和后台管理前端构建,仅用于调试已有发布包内容;正式发布不应使用该参数。
目标服务器启动:
```bash
@@ -186,7 +190,7 @@ cd build/<timestamp>
./stop.sh
```
如果后续通过 Jenkins 的部署脚本把发布包覆盖到固定部署目录,部署阶段默认只替换 `web/``api-server``spacetime_module.wasm``migration-bootstrap-secret.txt``scripts/``.env*``start.sh``stop.sh``web-server.mjs``README.md` 等发布产物;文件产物使用普通复制,`web/``scripts/` 等目录产物递归复制,不会删除部署目录中的 `.spacetimedb/``logs/``run/``deploy-state/``database-migrations/` 这类运行态目录。
如果后续通过 Jenkins 的部署脚本把发布包覆盖到固定部署目录,部署阶段默认只替换 `web/``api-server``spacetime_module.wasm``migration-bootstrap-secret.txt``scripts/``.env*``start.sh``stop.sh``web-server.mjs``README.md` 等发布产物;后台管理前端位于 `web/admin/`,随 `web/` 一并覆盖。文件产物使用普通复制,`web/``scripts/` 等目录产物递归复制,不会删除部署目录中的 `.spacetimedb/``logs/``run/``deploy-state/``database-migrations/` 这类运行态目录。
安全边界: