11 KiB
生产部署计划
更新时间:2026-05-02
目标
将当前部署方式调整为单机生产推荐方案:生产运行路径不使用 Docker,不再使用旧的一体化启动脚本,由 systemd 托管 SpacetimeDB 与 Rust api-server,由 Nginx 托管主站、后台前端与必要反向代理。
本计划用于重新创建 Jenkins 流水线、服务器环境配置、网站发布、api-server 发布、SpacetimeDB 模块发布,以及数据库人工导入导出流程。
生产架构
- Nginx 作为唯一公网入口,负责 HTTPS、静态站点、后台静态页面、维护页与
/admin/api/反向代理。 - SpacetimeDB 作为系统服务运行,监听
127.0.0.1:3000,数据根目录为/stdb。 - Rust
api-server作为系统服务运行,监听127.0.0.1:8082,只被 Nginx 的/admin/api/访问。 - 主站与后台前端构建为静态文件,发布到服务器固定目录,不放入 Jenkins 目录,也不跟随 Docker 镜像。
- 除网站静态发布外,
api-server发布、SpacetimeDB 模块发布、数据库导入、服务器配置变更都必须先进入维护模式。
服务器目录
/opt/genarrative/releases/<version>/:每次发布的完整版本目录。/opt/genarrative/current:指向当前生效版本的软链接。/srv/genarrative/web:指向/opt/genarrative/current/web,供 Nginx 托管静态站点。/etc/genarrative/api-server.env:api-server生产环境变量文件。/var/lib/genarrative/maintenance/enabled:维护模式开关文件。/stdb:SpacetimeDB 程序、配置与数据根目录。
生产密钥
/etc/genarrative/api-server.env 中的生产密钥指所有只能存在于生产服务器、不能进入 Git、不能进入构建产物的敏感配置。典型内容包括:
- LLM 或第三方服务 API Key。
- 短信服务 Access Key 与 Secret。
- 后台登录、会话、签名、加密相关密钥。
- 生产 SpacetimeDB 地址与数据库名。
- 只允许生产使用的回调地址、白名单或内部令牌。
该文件由服务器配置流水线或人工初始化创建,权限建议为 root:genarrative、0640。Jenkins 构建任务不能读取该文件;只有生产发布或服务启动需要读取。
systemd 服务
SpacetimeDB
- 服务名:
spacetimedb.service - 运行用户:
spacetimedb - 工作目录:
/stdb - 启动命令:
/stdb/spacetime --root-dir=/stdb start --listen-addr=127.0.0.1:3000 - 对外暴露:默认不直接暴露公网端口。
该方案与 SpacetimeDB 官方自托管文档一致:使用 Ubuntu、专用用户、/stdb 根目录、systemd 服务和 Nginx。
api-server
- 服务名:
genarrative-api.service - 运行用户:
genarrative - 工作目录:
/opt/genarrative/current - 可执行文件:
/opt/genarrative/current/api-server - 环境文件:
/etc/genarrative/api-server.env - 监听地址:
127.0.0.1:8082
api-server 不放入 Docker,也不直接暴露公网端口。发布时替换版本目录并重启 genarrative-api.service。
Nginx 规则
只保留必要入口:
/:主站静态页面。/admin/:后台前端静态页面,后台构建时使用/admin/作为 base path。/admin/api/:反向代理到http://127.0.0.1:8082/admin/api/。- HTTP 到 HTTPS:只保留 301 重定向。
/maintenance.html:维护中页面。
移除这些公网反向代理:
/api/*/generated-*- 公网
/healthz - 其他旧的一体化 web server 代理入口。
SpacetimeDB 公网路由默认保持收敛,只按实际前端 SDK 需要暴露最小集合。禁止开放可远程发布数据库或管理实例的通用入口。
维护模式
维护模式由 /var/lib/genarrative/maintenance/enabled 控制:
- 文件存在:进入维护模式。
- 文件不存在:退出维护模式。
行为:
- 网站静态资源发布不进入维护模式。
api-server发布、SpacetimeDB 模块发布、数据库导入、服务器配置变更必须进入维护模式。- 普通页面在维护模式下展示
/maintenance.html。 /admin/api/*在维护模式下返回 503。- 静态资源仍允许访问,避免维护页样式和资源加载失败。
- 发布成功后自动解除维护模式。
- 发布失败时保持维护模式,并通过邮件通知人工处理。
构建产物
每次构建产物按版本号归档:
build/<version>/
├─ web/
│ ├─ index.html
│ ├─ assets/
│ ├─ maintenance.html
│ └─ admin/
├─ api-server
├─ spacetime_module.wasm
├─ scripts/
│ ├─ spacetime-publish-prod.sh
│ ├─ database-export.sh
│ ├─ database-import.sh
│ ├─ maintenance-on.sh
│ ├─ maintenance-off.sh
│ └─ maintenance-status.sh
├─ deploy/
│ ├─ systemd/
│ │ ├─ spacetimedb.service
│ │ └─ genarrative-api.service
│ ├─ nginx/
│ │ ├─ genarrative.conf
│ │ └─ snippets/maintenance.conf
│ └─ env/api-server.env.example
└─ README.md
不再生成旧产物:
web-server.mjs- 旧的一体化
start.sh - 旧的一体化
stop.sh
Jenkins 节点
Jenkins 可运行在 Windows 或其他机器上,但构建与发布动作使用 Linux agent。
开发/构建实例
- 节点名:
genarrative-dev - 标签:
genarrative-linux dev build - 用途:拉代码、安装依赖、构建主站、构建后台、构建
api-server、构建 SpacetimeDB wasm、归档产物。
生产/发布实例
- 节点名:
genarrative-prod - 标签:
genarrative-linux prod deploy - 用途:服务器配置、发布静态网站、发布
api-server、发布 SpacetimeDB 模块、数据库导入导出、维护模式切换。
SSH PEM 凭证
在 Jenkins 中使用 SSH Username with private key 类型添加 PEM 私钥:
genarrative-dev-ssh-key:开发/构建实例 SSH 凭证。genarrative-prod-ssh-key:生产/发布实例 SSH 凭证。
推荐使用非 root 用户,例如 jenkins。该用户只通过 sudoers 获得必要命令权限,例如 systemctl restart genarrative-api、nginx -t、维护脚本、发布目录切换等。
Jenkins 流水线
计划重新创建以下流水线:
Genarrative-Server-ProvisionGenarrative-Web-BuildGenarrative-Web-DeployGenarrative-Api-BuildGenarrative-Api-DeployGenarrative-Stdb-Module-BuildGenarrative-Stdb-Module-PublishGenarrative-Database-ExportGenarrative-Database-ImportGenarrative-Full-Build-And-Deploy
构建流水线运行在 build && dev,发布、导入导出和服务器配置流水线运行在 deploy && prod。
构建流水线支持参数 PUBLISH_AFTER_BUILD:
false:只构建并归档产物。true:构建成功后触发对应发布流水线。
发布流水线必须从归档产物获取文件,不依赖构建 workspace 的本地状态。
流水线职责
Genarrative-Server-Provision
用于生产服务器一次性或低频配置:
- 创建
spacetimedb、genarrative等系统用户。 - 创建
/stdb、/opt/genarrative、/srv/genarrative、/etc/genarrative、/var/lib/genarrative/maintenance。 - 安装或更新 SpacetimeDB。
- 安装 systemd unit。
- 安装 Nginx 配置和维护模式 snippet。
- 执行
nginx -t。 - 启用并启动
spacetimedb.service与genarrative-api.service。
该流水线属于高风险操作,默认要求人工确认后执行。
Web Build / Deploy
构建:
- 构建主站静态文件。
- 构建后台前端,base path 为
/admin/。 - 生成或复制
maintenance.html。 - 归档
web/产物。
发布:
- 解包到
/opt/genarrative/releases/<version>/web。 - 更新
/opt/genarrative/current与/srv/genarrative/web指向。 - 执行 Nginx 配置测试和静态页面 smoke test。
- 不进入维护模式。
Api Build / Deploy
构建:
- 编译 Rust
api-server。 - 归档单一可执行文件和必要运行说明。
发布:
- 进入维护模式。
- 解包到
/opt/genarrative/releases/<version>/api-server。 - 更新
/opt/genarrative/current。 - 重启
genarrative-api.service。 - 检查本机
/healthz。 - 成功后解除维护模式。
- 失败时保留维护模式并发邮件。
Stdb Module Build / Publish
构建:
- 使用
spacetime build构建spacetime_module.wasm。 - 归档 wasm 与发布脚本。
发布:
- 进入维护模式。
- 将 wasm 上传到生产实例。
- 在生产实例本机执行
spacetime publish -s local --bin-path spacetime_module.wasm <database-name>。 - 成功后执行必要 smoke test。
- 成功后解除维护模式。
- 失败时保留维护模式并发邮件。
数据库导出与导入
导出
Genarrative-Database-Export 用于人工导出生产数据:
- 运行在
deploy && prod。 - 进入维护模式,避免导出期间继续写入。
- 从本机 SpacetimeDB 导出指定数据库数据。
- 产物归档到 Jenkins,并可额外保存到服务器备份目录。
- 成功后解除维护模式。
- 失败时保留维护模式并邮件通知。
导入
Genarrative-Database-Import 用于人工导入或恢复数据:
- 运行在
deploy && prod。 - 必须要求人工确认目标数据库、导入文件和是否覆盖。
- 进入维护模式。
- 导入前先生成一次安全备份。
- 执行导入。
- 执行数据校验和服务 smoke test。
- 成功后解除维护模式。
- 失败时保留维护模式并邮件通知。
数据库表结构变更必须同步检查并更新 migration.rs,不能只发布 wasm。
全量构建并发布
Genarrative-Full-Build-And-Deploy 顺序:
- 触发
Genarrative-Web-Build。 - 触发
Genarrative-Api-Build。 - 触发
Genarrative-Stdb-Module-Build。 - 触发
Genarrative-Stdb-Module-Publish。 - 触发
Genarrative-Api-Deploy。 - 触发
Genarrative-Web-Deploy。 - 执行生产 smoke test。
网站最后发布,避免后台或主站提前指向尚未完成发布的后端能力。
回滚
- 网站回滚:将
/srv/genarrative/web或/opt/genarrative/current切回上一版本并 reload Nginx。 api-server回滚:将/opt/genarrative/current切回上一版本并重启genarrative-api.service。- SpacetimeDB 模块回滚:发布上一版本
spacetime_module.wasm。 - 数据回滚:使用导入流水线恢复指定备份,必须进入维护模式。
待落地文件
后续工程落地时需要新增或改造:
deploy/systemd/spacetimedb.servicedeploy/systemd/genarrative-api.servicedeploy/nginx/genarrative.confdeploy/nginx/snippets/maintenance.confdeploy/env/api-server.env.examplescripts/deploy/maintenance-on.shscripts/deploy/maintenance-off.shscripts/deploy/maintenance-status.sh- 新 Jenkinsfile 或 Job DSL,用于上述 10 条流水线。
- 更新旧部署文档,标记旧一体化脚本为废弃或迁移对象。
参考
- SpacetimeDB 官方自托管文档:https://spacetimedb.com/docs/how-to/deploy/self-hosting/