Files
Genarrative/生产部署计划.md
2026-05-02 02:58:14 +08:00

11 KiB
Raw Blame History

生产部署计划

更新时间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.envapi-server 生产环境变量文件。
  • /var/lib/genarrative/maintenance/enabled:维护模式开关文件。
  • /stdbSpacetimeDB 程序、配置与数据根目录。

生产密钥

/etc/genarrative/api-server.env 中的生产密钥指所有只能存在于生产服务器、不能进入 Git、不能进入构建产物的敏感配置。典型内容包括

  • LLM 或第三方服务 API Key。
  • 短信服务 Access Key 与 Secret。
  • 后台登录、会话、签名、加密相关密钥。
  • 生产 SpacetimeDB 地址与数据库名。
  • 只允许生产使用的回调地址、白名单或内部令牌。

该文件由服务器配置流水线或人工初始化创建,权限建议为 root:genarrative0640。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-apinginx -t、维护脚本、发布目录切换等。

Jenkins 流水线

计划重新创建以下流水线:

  1. Genarrative-Server-Provision
  2. Genarrative-Web-Build
  3. Genarrative-Web-Deploy
  4. Genarrative-Api-Build
  5. Genarrative-Api-Deploy
  6. Genarrative-Stdb-Module-Build
  7. Genarrative-Stdb-Module-Publish
  8. Genarrative-Database-Export
  9. Genarrative-Database-Import
  10. Genarrative-Full-Build-And-Deploy

构建流水线运行在 build && dev,发布、导入导出和服务器配置流水线运行在 deploy && prod

构建流水线支持参数 PUBLISH_AFTER_BUILD

  • false:只构建并归档产物。
  • true:构建成功后触发对应发布流水线。

发布流水线必须从归档产物获取文件,不依赖构建 workspace 的本地状态。

流水线职责

Genarrative-Server-Provision

用于生产服务器一次性或低频配置:

  • 创建 spacetimedbgenarrative 等系统用户。
  • 创建 /stdb/opt/genarrative/srv/genarrative/etc/genarrative/var/lib/genarrative/maintenance
  • 安装或更新 SpacetimeDB。
  • 安装 systemd unit。
  • 安装 Nginx 配置和维护模式 snippet。
  • 执行 nginx -t
  • 启用并启动 spacetimedb.servicegenarrative-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 顺序:

  1. 触发 Genarrative-Web-Build
  2. 触发 Genarrative-Api-Build
  3. 触发 Genarrative-Stdb-Module-Build
  4. 触发 Genarrative-Stdb-Module-Publish
  5. 触发 Genarrative-Api-Deploy
  6. 触发 Genarrative-Web-Deploy
  7. 执行生产 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.service
  • deploy/systemd/genarrative-api.service
  • deploy/nginx/genarrative.conf
  • deploy/nginx/snippets/maintenance.conf
  • deploy/env/api-server.env.example
  • scripts/deploy/maintenance-on.sh
  • scripts/deploy/maintenance-off.sh
  • scripts/deploy/maintenance-status.sh
  • 新 Jenkinsfile 或 Job DSL用于上述 10 条流水线。
  • 更新旧部署文档,标记旧一体化脚本为废弃或迁移对象。

参考