7.9 KiB
7.9 KiB
Rust 本地联调与远端发布脚本方案
日期:2026-04-22
1. 目标
本方案补齐 server-rs 在 M7 切流前需要的两类工程脚本:
- 本地一键联调脚本:同时启动本地 SpacetimeDB、Rust
api-server与 Web 前端,并通过现有 Vite 代理开关把运行时 API 指向 Rust。 - Ubuntu 发布包构建脚本:在仓库根目录生成
build/<当前时间>/发布目录,内含前端 release、Linuxapi-server、SpacetimeDB wasm、启动脚本、停止脚本,以及从仓库根目录复制的.env/.env.local,并默认通过scp上传到目标服务器。
脚本只做部署与联调编排,不改变 HTTP contract、SpacetimeDB schema 命名、对象存储键规划和前端默认 Node 开发入口。
2. 本地脚本
入口:
npm run dev:rust
跨平台 Bash 入口:
npm run dev:rust:sh
Windows 下 dev:rust:sh、deploy:rust:remote 与 build:rust:ubuntu 会通过 scripts/run-bash-script.mjs 优先查找 Git Bash;如安装路径不标准,可用 GENARRATIVE_BASH 指定 bash 可执行文件。
默认端口:
- Web 前端:
http://127.0.0.1:3000 - Rust
api-server:http://127.0.0.1:8082 - SpacetimeDB standalone:
http://127.0.0.1:3101 - SpacetimeDB database:优先读取仓库根目录
spacetime.local.json的database字段;没有该字段时才回退到genarrative-dev
默认流程:
- 检查
cargo、node与spacetimeCLI。 - 启动
spacetime --root-dir server-rs/.spacetimedb/local start --edition standalone --listen-addr 127.0.0.1:3101。 - 等待
spacetime server ping http://127.0.0.1:3101可用。 - 执行
spacetime publish <本地数据库名> --server http://127.0.0.1:3101 --module-path server-rs/crates/spacetime-module --yes。 - 注入
GENARRATIVE_API_*与GENARRATIVE_SPACETIME_*后启动cargo run -p api-server;直接运行api-server时,如未显式设置GENARRATIVE_SPACETIME_DATABASE,服务端也会向上查找spacetime.local.json作为本地默认库名。 - 注入
GENARRATIVE_BACKEND_STACK=rust、RUST_SERVER_TARGET、GENARRATIVE_RUNTIME_SERVER_TARGET后启动 Vite。 - 任一子进程退出时,脚本回收其余子进程。
Vite 代理覆盖范围:
/api/runtime/*会在 Rust 栈下代理到 Rustapi-server,覆盖旧 runtime story 兼容接口。/api/story/*会在 Rust 栈下代理到 Rustapi-server,覆盖新 story session、battle 查询与 NPC battle 切片接口。- 其他
/api/auth、/api/assets、/api/custom-world、/api/llm等路径仍由同一个GENARRATIVE_RUNTIME_SERVER_TARGET控制,便于 M7 按服务能力逐项做对比 smoke。
安全边界:
- 默认不执行
--clear-database。 - 只有显式传入
-ClearDatabase或--clear-database才允许清库重发。 - 如需要复用已经启动的 SpacetimeDB,可传
-SkipSpacetime/--skip-spacetime。 - 如只想启动进程不发布模块,可传
-SkipPublish/--skip-publish。
常用示例:
.\scripts\dev-rust-stack.ps1
.\scripts\dev-rust-stack.ps1 -ApiPort 8090 -SpacetimePort 3110 -Database genarrative-dev
.\scripts\dev-rust-stack.ps1 -SkipSpacetime -SkipPublish
.\scripts\dev-rust-stack.ps1 -ClearDatabase
./scripts/dev-rust-stack.sh
./scripts/dev-rust-stack.sh --api-port 8090 --spacetime-port 3110 --database genarrative-dev
./scripts/dev-rust-stack.sh --skip-spacetime --skip-publish
./scripts/dev-rust-stack.sh --clear-database
联调排错补充:
- 如果首页公开广场出现
上游服务请求失败,优先检查api-server错误详情里的ws://.../v1/database/<database>/subscribe是否指向了未发布的库。 spacetime list --server http://127.0.0.1:3101应能看到spacetime.local.json中的库名;若没有,执行spacetime publish <本地数据库名> --server http://127.0.0.1:3101 --module-path server-rs/crates/spacetime-module --yes。- 发布库名与
GENARRATIVE_SPACETIME_DATABASE不一致时,/api/runtime/custom-world-gallery会从 Rustapi-server返回502,前端首页只能展示空态或错误提示,无法自行修复。
3. Ubuntu 发布包脚本
入口:
npm run build:rust:ubuntu
兼容入口:
npm run deploy:rust:remote
保留 deploy:rust:remote 是为了不打断既有命令习惯;当前语义已调整为“生成 Ubuntu 发布包”,不再通过 SSH 进入服务器执行部署。
默认流程:
- 在仓库根目录创建
build/。 - 在
build/下创建当前时间命名的目标目录,例如build/20260422-153000/。 - 使用 Vite 构建前端 release 到目标目录的
web/。 - 执行
cargo build -p api-server --release --target x86_64-unknown-linux-gnu --manifest-path server-rs/Cargo.toml,并把api-server复制到目标目录。 - 执行
cargo build -p spacetime-module --release --target wasm32-unknown-unknown --manifest-path server-rs/Cargo.toml,并把spacetime_module.wasm复制到目标目录。 - 把仓库根目录的
.env与.env.local分别复制到目标目录根部和目标目录的web/下。 - 在目标目录写入
web-server.mjs,用于托管web/并把/api/*、/generated-*、/healthz反代到本包内的api-server。 - 在目标目录写入
start.sh与stop.sh;start.sh会先加载发布目录根部的.env、.env.local,再回退到构建时通过--database、--api-port、--web-port、--spacetime-host、--spacetime-port写入的默认值。 - 默认执行
scp -r -i ~\.ssh\dsk.pem build/<timestamp> ubuntu@82.157.175.59:/home/ubuntu/genarrative/上传发布包。
发布包结构:
build/<timestamp>/
├─ .env
├─ .env.local
├─ web/
│ ├─ .env
│ └─ .env.local
├─ api-server
├─ spacetime_module.wasm
├─ web-server.mjs
├─ start.sh
├─ stop.sh
└─ README.md
常用示例:
npm run build:rust:ubuntu -- --name 20260422-153000
npm run build:rust:ubuntu -- --database genarrative-dev --web-port 3000 --api-port 8082 --spacetime-port 3101
npm run build:rust:ubuntu -- --skip-upload
目标服务器启动:
cd build/<timestamp>
./start.sh
./stop.sh
如果后续通过 Jenkins 的部署脚本把发布包覆盖到固定部署目录,部署阶段默认只替换 web/、api-server、spacetime_module.wasm、.env*、start.sh、stop.sh、web-server.mjs、README.md 等发布产物,不会删除部署目录中的 spacetimedb-data/、logs/、run/ 这类运行态目录。
安全边界:
- 构建脚本会把仓库根目录已有的
.env、.env.local一并复制进发布包,因此运行前必须确认这些文件内容适合被带入目标环境。 - 如果仓库根目录不存在
.env或.env.local,脚本会打印跳过日志,但不会因此失败;此时start.sh仅使用构建时写入的默认值与运行时显式传入的环境变量。 start.sh默认不清空 SpacetimeDB;只有显式执行./start.sh --clear-database才允许清库重发。start.sh使用spacetime publish --bin-path spacetime_module.wasm --yes发布当前包内 wasm。- 当前脚本是单目录进程启动方案,不替代生产 systemd、Nginx、TLS、日志轮转与守护进程配置。
- 如只需要本地生成发布包,可传
--skip-upload跳过默认 scp 上传。
目标服务器最小要求:
- Ubuntu x86_64。
- 已安装
node,用于运行发布包内的web-server.mjs。 - 已安装
spacetimeCLI,start.sh会启动本地 SpacetimeDB 并发布 wasm。 - 业务密钥通过目标服务器环境变量或发布包同目录
.env.local提供。
4. 与 M7 的关系
这套脚本补齐 M7 的部署执行入口,但不等价于完成灰度切流。M7 后续仍需要在真实 OSS、LLM、短信、微信、SpacetimeDB 数据库和反向代理环境下完成全链路 smoke、关键 SSE 联调和灰度切流验收。