Files
Genarrative/docs/technical/RUST_LOCAL_AND_REMOTE_DEPLOYMENT_SCRIPTS_2026-04-22.md

8.1 KiB
Raw Blame History

Rust 本地联调与远端发布脚本方案

日期:2026-04-22

1. 目标

本方案补齐 server-rs 在 M7 切流前需要的两类工程脚本:

  1. 本地一键联调脚本:同时启动本地 SpacetimeDB、Rust api-server 与 Web 前端,并通过现有 Vite 代理开关把运行时 API 指向 Rust。
  2. Ubuntu 发布包构建脚本:在仓库根目录生成 build/<当前时间>/ 发布目录,内含前端 release、Linux api-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:shdeploy:rust:remotebuild:rust:ubuntu 会通过 scripts/run-bash-script.mjs 优先查找 Git Bash如安装路径不标准可用 GENARRATIVE_BASH 指定 bash 可执行文件。

默认端口:

  1. Web 前端:http://127.0.0.1:3000
  2. Rust api-serverhttp://127.0.0.1:8082
  3. SpacetimeDB standalonehttp://127.0.0.1:3101
  4. SpacetimeDB database优先读取仓库根目录 spacetime.local.jsondatabase 字段;没有该字段时才回退到 genarrative-dev

默认流程:

  1. 检查 cargonodespacetime CLI。
  2. 启动 spacetime --root-dir server-rs/.spacetimedb/local start --edition standalone --listen-addr 127.0.0.1:3101
  3. 等待 spacetime server ping http://127.0.0.1:3101 可用。
  4. 执行 spacetime publish <本地数据库名> --server http://127.0.0.1:3101 --module-path server-rs/crates/spacetime-module --yes
  5. 注入 GENARRATIVE_API_*GENARRATIVE_SPACETIME_* 后启动 cargo run -p api-server;直接运行 api-server 时,如未显式设置 GENARRATIVE_SPACETIME_DATABASE,服务端也会向上查找 spacetime.local.json 作为本地默认库名。
  6. 注入 GENARRATIVE_BACKEND_STACK=rustRUST_SERVER_TARGETGENARRATIVE_RUNTIME_SERVER_TARGET 后启动 Vite。
  7. 任一子进程退出时,脚本回收其余子进程。

Vite 代理覆盖范围:

  1. /api/runtime/* 会在 Rust 栈下代理到 Rust api-server,覆盖旧 runtime story 兼容接口。
  2. /api/story/* 会在 Rust 栈下代理到 Rust api-server,覆盖新 story session、battle 查询与 NPC battle 切片接口。
  3. 其他 /api/auth/api/assets/api/custom-world/api/llm 等路径仍由同一个 GENARRATIVE_RUNTIME_SERVER_TARGET 控制,便于 M7 按服务能力逐项做对比 smoke。

安全边界:

  1. 默认不执行 --clear-database
  2. 只有显式传入 -ClearDatabase--clear-database 才允许清库重发。
  3. 如需要复用已经启动的 SpacetimeDB可传 -SkipSpacetime / --skip-spacetime
  4. 如只想启动进程不发布模块,可传 -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

联调排错补充:

  1. 如果首页公开广场出现 上游服务请求失败,优先检查 api-server 错误详情里的 ws://.../v1/database/<database>/subscribe 是否指向了未发布的库。
  2. 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
  3. 发布库名与 GENARRATIVE_SPACETIME_DATABASE 不一致时,/api/runtime/custom-world-gallery 会从 Rust api-server 返回 502,前端首页只能展示空态或错误提示,无法自行修复。

3. Ubuntu 发布包脚本

入口:

npm run build:rust:ubuntu

兼容入口:

npm run deploy:rust:remote

保留 deploy:rust:remote 是为了不打断既有命令习惯;当前语义已调整为“生成 Ubuntu 发布包”,不再通过 SSH 进入服务器执行部署。

默认流程:

  1. 在仓库根目录创建 build/
  2. build/ 下创建当前时间命名的目标目录,例如 build/20260422-153000/
  3. 使用 Vite 构建前端 release 到目标目录的 web/
  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/ 下。
  7. 在目标目录写入 web-server.mjs,用于托管 web/ 并把 /api/*/generated-*/healthz 反代到本包内的 api-server
  8. 在目标目录写入 start.shstop.shstart.sh 会先加载发布目录根部的 .env.env.local,再回退到构建时通过 --database--api-port--web-port--spacetime-host--spacetime-port 写入的默认值,并默认导出 NO_COLOR=1CARGO_TERM_COLOR=never,避免 ANSI 控制码写入日志文件;如果以 --clear-database 启动,则内部 spacetime publish 会追加 -c always
  9. 默认执行 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-serverspacetime_module.wasm.env*start.shstop.shweb-server.mjsREADME.md 等发布产物,不会删除部署目录中的 spacetimedb-data/logs/run/ 这类运行态目录。

安全边界:

  1. 构建脚本会把仓库根目录已有的 .env.env.local 一并复制进发布包,因此运行前必须确认这些文件内容适合被带入目标环境。
  2. 如果仓库根目录不存在 .env.env.local,脚本会打印跳过日志,但不会因此失败;此时 start.sh 仅使用构建时写入的默认值与运行时显式传入的环境变量。
  3. start.sh 默认不清空 SpacetimeDB只有显式执行 ./start.sh --clear-database 才允许清库重发。
  4. start.sh 使用 spacetime publish --bin-path spacetime_module.wasm --yes 发布当前包内 wasm清库模式下会追加 -c always
  5. 当前脚本是单目录进程启动方案,不替代生产 systemd、Nginx、TLS、日志轮转与守护进程配置。
  6. 如只需要本地生成发布包,可传 --skip-upload 跳过默认 scp 上传。

目标服务器最小要求:

  1. Ubuntu x86_64。
  2. 已安装 node,用于运行发布包内的 web-server.mjs
  3. 已安装 spacetime CLIstart.sh 会启动本地 SpacetimeDB 并发布 wasm。
  4. 业务密钥通过目标服务器环境变量或发布包同目录 .env.local 提供。

4. 与 M7 的关系

这套脚本补齐 M7 的部署执行入口但不等价于完成灰度切流。M7 后续仍需要在真实 OSS、LLM、短信、微信、SpacetimeDB 数据库和反向代理环境下完成全链路 smoke、关键 SSE 联调和灰度切流验收。