Add production Jenkins release pipelines

This commit is contained in:
2026-05-02 19:14:13 +08:00
parent 879a53bf8d
commit bdc3257003
38 changed files with 3315 additions and 982 deletions

View File

@@ -2,6 +2,8 @@
日期:`2026-04-23`
状态:历史方案,已被 `PRODUCTION_DEPLOYMENT_PLAN_2026-05-02.md` 中的 `jenkins/Jenkinsfile.production-*` 生产流水线替代。旧 Jenkinsfile 已从仓库删除,本文只保留旧本地目录部署链的设计背景和迁移参考,不能再作为新 Jenkins Job 的脚本路径来源。
## 1. 目标
本方案为当前仓库补齐 3 条 Jenkins 流水线:
@@ -47,11 +49,7 @@
### 4.1 构建
脚本路径:
```text
jenkins/Jenkinsfile.build
```
脚本路径:`jenkins/Jenkinsfile.build`。该文件当前仓库已不存在;生产构建改用 `jenkins/Jenkinsfile.production-web-build``jenkins/Jenkinsfile.production-api-build``jenkins/Jenkinsfile.production-stdb-module-build`
核心流程:
@@ -74,11 +72,7 @@ BUILD_VERSION = Jenkins BUILD_NUMBER
### 4.2 部署
脚本路径:
```text
jenkins/Jenkinsfile.deploy
```
脚本路径:`jenkins/Jenkinsfile.deploy`。该文件当前仓库已删除;生产发布改用 `jenkins/Jenkinsfile.production-web-deploy``jenkins/Jenkinsfile.production-api-deploy``jenkins/Jenkinsfile.production-stdb-module-publish`
核心流程:
@@ -114,11 +108,7 @@ scripts/jenkins-deploy-release.sh \
### 4.3 构建并部署
脚本路径:
```text
jenkins/Jenkinsfile.build-and-deploy
```
脚本路径:`jenkins/Jenkinsfile.build-and-deploy`。该文件当前仓库已删除;全量编排改用 `jenkins/Jenkinsfile.production-full-build-and-deploy`,并按 Web / API / Stdb 并行构建、Stdb / API / Web 顺序发布执行。
核心流程:
@@ -198,11 +188,11 @@ jenkins ALL=(root) NOPASSWD: /var/lib/jenkins/deploy/Genarrative/stop.sh
## 6. 推荐 Job 命名
建议在 Jenkins 中创建以下 3 个 Pipeline Job并分别指向仓库中的脚本路径
以下旧 Job 命名只保留为历史记录,不再创建或关联到仓库脚本
1. `Genarrative-Build` -> `jenkins/Jenkinsfile.build`
2. `Genarrative-Deploy` -> `jenkins/Jenkinsfile.deploy`
3. `Genarrative-Build-And-Deploy` -> `jenkins/Jenkinsfile.build-and-deploy`
1. `Genarrative-Build`
2. `Genarrative-Deploy`
3. `Genarrative-Build-And-Deploy`
同时给 `Genarrative-Deploy` 配置环境变量:
@@ -218,14 +208,7 @@ game/Genarrative-Build-And-Deploy
## 7. 文件清单
本方案对应的仓库文件:
```text
jenkins/Jenkinsfile.build
jenkins/Jenkinsfile.deploy
jenkins/Jenkinsfile.build-and-deploy
scripts/jenkins-deploy-release.sh
```
本方案对应 Jenkinsfile 已删除。生产发布链的当前文件清单见 `PRODUCTION_DEPLOYMENT_PLAN_2026-05-02.md`;旧部署脚本如 `scripts/jenkins-deploy-release.sh` 只作为旧发布包链路参考,不再作为生产 Jenkins 入口。
## 8. 风险与边界

View File

@@ -2,6 +2,8 @@
日期:`2026-04-29`
状态:历史方案。旧数据库导入导出 Jenkinsfile 已从仓库删除,生产版 `Genarrative-Database-Export` / `Genarrative-Database-Import` 已按 `PRODUCTION_DEPLOYMENT_PLAN_2026-05-02.md` 落地到 `jenkins/Jenkinsfile.production-database-export``jenkins/Jenkinsfile.production-database-import`。本文只保留迁移脚本参数、权限边界和 `CHUNK_SIZE` 等经验;生产 Job 入口以生产部署计划和 `jenkins/Jenkinsfile.production-*` 为准。
## 1. 目标
为 Jenkins 增加两条人工触发的数据库迁移流水线:
@@ -24,11 +26,7 @@
### 3.1 数据库导出
脚本路径:
```text
jenkins/Jenkinsfile.database-export
```
脚本路径:`jenkins/Jenkinsfile.database-export`。该文件当前仓库已删除;生产版入口为 `jenkins/Jenkinsfile.production-database-export`
推荐作业名:
@@ -38,28 +36,30 @@ Genarrative-Database-Export
关键参数:
1. `DATABASE`:目标 SpacetimeDB 数据库名;留空时读取仓库环境变量
2. `SERVER`SpacetimeDB server 别名,默认 `maincloud`
3. `SERVER_URL`:显式服务地址;填写后优先于 `SERVER`
4. `DEPLOY_DIRECTORY`:固定部署目录,默认 `/var/lib/jenkins/deploy/Genarrative`
5. `ROOT_DIR`:可选,透传给 `spacetime --root-dir`;为空时使用 `<DEPLOY_DIRECTORY>/.spacetimedb`
6. `INCLUDE_TABLES`:可选,逗号分隔的表名白名单
7. `OUTPUT_DIRECTORY`:导出文件目录,默认 `database-exports`
8. `EXPORT_NAME`:导出文件名;留空时使用 `spacetime-migration-<BUILD_NUMBER>.json`
1. `DEPLOY_TARGET`:逻辑导出目标,`development` 映射到 `linux && genarrative-build``release` 映射到 `linux && genarrative-release-deploy`
2. `CONFIRM_RELEASE_DEPLOY_AGENT``DEPLOY_TARGET=release` 时必填确认
3. `SOURCE_BRANCH` / `COMMIT_HASH`:固定本次执行的迁移脚本版本
4. `DATABASE`:必填,目标 SpacetimeDB 数据库名
5. `SPACETIME_SERVER`SpacetimeDB server 别名,默认 `local`
6. `SPACETIME_SERVER_URL`:显式服务地址;填写后优先于 `SPACETIME_SERVER`
7. `SPACETIME_ROOT_DIR``spacetime --root-dir`,默认 `/stdb`
8. `INCLUDE_TABLES`:可选,逗号分隔的表名白名单
9. `WORKSPACE_EXPORT_DIRECTORY`Jenkins workspace 内导出目录,默认 `database-exports`
10. `SERVER_BACKUP_DIRECTORY`:可选,目标机器上的额外备份目录;留空则不保存服务器副本。
11. `EXPORT_NAME`:导出文件名;留空时使用 `spacetime-migration-<BUILD_NUMBER>.json`
12. `TOKEN_CREDENTIAL_ID`:可选,已授权迁移 operator token 的 Jenkins Secret Text 凭据 ID。
13. `BOOTSTRAP_SECRET_CREDENTIAL_ID`:可选,迁移 bootstrap secret 的 Jenkins Secret Text 凭据 ID。
导出成功后Jenkins 归档:
```text
<OUTPUT_DIRECTORY>/<EXPORT_NAME>
<WORKSPACE_EXPORT_DIRECTORY>/<EXPORT_NAME>
<WORKSPACE_EXPORT_DIRECTORY>/<EXPORT_NAME>.sha256
```
### 3.2 数据库导入
脚本路径:
```text
jenkins/Jenkinsfile.database-import
```
脚本路径:`jenkins/Jenkinsfile.database-import`。该文件当前仓库已删除;生产版入口为 `jenkins/Jenkinsfile.production-database-import`
推荐作业名:
@@ -69,25 +69,29 @@ Genarrative-Database-Import
关键参数:
1. `INPUT_FILE`:必填,迁移 JSON 文件路径
2. `DATABASE``SERVER``SERVER_URL``DEPLOY_DIRECTORY``ROOT_DIR`:与导出流水线一致
3. `INCLUDE_TABLES`可选,只导入指定表
4. `CHUNK_SIZE`:迁移 JSON 分片大小,默认 `524288` bytes。导入脚本会在文件超过该大小或直接导入触发 HTTP 413 时自动分片上传
5. `DRY_RUN`:默认 `true`,只校验不写入
6. `INCREMENTAL`:默认 `true`,跳过已存在或冲突的行
7. `REPLACE_EXISTING`:默认 `false`,只覆盖本次迁移文件中涉及的表;不可与 `INCREMENTAL` 同时启用
8. `BOOTSTRAP_SECRET`:可选,用于授权临时 Web API identity
9. `TOKEN`可选SpacetimeDB 客户端连接 token留空时脚本会自动创建临时 identity 并在结束后撤销
10. `NOTE`:迁移授权备注
1. `INPUT_SOURCE`:必填,`pipeline_archive` 表示从 `Genarrative-Database-Export` 归档复制输入文件,`manual_upload` 表示本次构建手动上传数据源;两种方式互斥
2. `EXPORT_JOB_NAME` / `EXPORT_BUILD_NUMBER_TO_IMPORT` / `INPUT_FILE`:仅 `pipeline_archive` 模式使用。`EXPORT_JOB_NAME` 默认是导出流水线 `Genarrative-Database-Export``INPUT_FILE` 可留空,留空时按导出流水线默认归档路径解析为 `database-exports/spacetime-migration-<导出构建号>.json`
3. `MANUAL_INPUT_FILE``manual_upload` 模式使用Jenkins 通过 file parameter 接收本次构建上传文件
4. `DATABASE``SERVER``SERVER_URL``DEPLOY_DIRECTORY``ROOT_DIR`:与导出流水线一致
5. `INCLUDE_TABLES`:可选,只导入指定表
6. `CHUNK_SIZE`:迁移 JSON 分片大小,默认 `524288` bytes。导入脚本会在文件超过该大小或直接导入触发 HTTP 413 时自动分片上传
7. `DRY_RUN`:默认 `true`,只校验不写入
8. `INCREMENTAL`:默认 `true`,跳过已存在或冲突的行
9. `REPLACE_EXISTING`:默认 `false`,只覆盖本次迁移文件中涉及的表;不可与 `INCREMENTAL` 同时启用
10. `BOOTSTRAP_SECRET`:可选,用于授权临时 Web API identity
11. `TOKEN`可选SpacetimeDB 客户端连接 token留空时脚本会自动创建临时 identity 并在结束后撤销。
12. `NOTE`:迁移授权备注。
## 4. 安全边界
1. 导入流水线默认 `DRY_RUN=true`,需要人工明确关闭才会写入数据。
2. `INCREMENTAL``REPLACE_EXISTING` 互斥Jenkinsfile 会在执行前阻止同时启用。
3. Jenkinsfile 不打印 token生产环境应通过 Jenkins 凭据或目标机器环境变量传入敏感值
4. 如果不传 `TOKEN`,导入脚本会创建临时 Web API identity并调用迁移授权/撤销 procedure 收敛权限窗口
5. 导入导出流水线在调用仓库内迁移脚本前都会执行 `git reset --hard HEAD`,确保固定源码目录中的本地改动不会影响本次迁移操作
6. 如果日志出现 `SpacetimeDB HTTP 413: Failed to buffer the request body: length limit exceeded`,优先把 `CHUNK_SIZE` 调低到 `262144` 或更小后重跑。该参数只降低单次 HTTP body不改变导入表范围
3. `INPUT_SOURCE=pipeline_archive` 时必须填写 `EXPORT_BUILD_NUMBER_TO_IMPORT``EXPORT_JOB_NAME` 默认使用导出流水线名称,`INPUT_FILE` 默认使用导出流水线默认归档路径,只有导出时自定义目录或文件名才需要显式填写
4. `INPUT_SOURCE=manual_upload` 时必须上传 `MANUAL_INPUT_FILE`,并把 `CONFIRM_INPUT_FILE` 填成原始文件名;`EXPORT_JOB_NAME` 的默认值可以保留,不参与该模式的输入边界
5. Jenkinsfile 不打印 token生产环境应通过 Jenkins 凭据或目标机器环境变量传入敏感值
6. 如果不传 `TOKEN`,导入脚本会创建临时 Web API identity并调用迁移授权/撤销 procedure 收敛权限窗口
7. 导入导出流水线在调用仓库内迁移脚本前都会执行 `git reset --hard HEAD`,确保固定源码目录中的本地改动不会影响本次迁移操作。
8. 如果日志出现 `SpacetimeDB HTTP 413: Failed to buffer the request body: length limit exceeded`,优先把 `CHUNK_SIZE` 调低到 `262144` 或更小后重跑。该参数只降低单次 HTTP body不改变导入表范围。
## 5. 本地部署测试参数
@@ -112,7 +116,7 @@ DEPLOY_DIRECTORY=/var/lib/jenkins/deploy/Genarrative
## 6. 文件清单
```text
jenkins/Jenkinsfile.database-export
jenkins/Jenkinsfile.database-import
jenkins/Jenkinsfile.production-database-export
jenkins/Jenkinsfile.production-database-import
docs/technical/JENKINS_SPACETIMEDB_DATABASE_MIGRATION_PIPELINES_2026-04-29.md
```

View File

@@ -0,0 +1,518 @@
# 生产部署计划
更新时间2026-05-02
## 当前落地进度
已落地生产基础设施骨架与首批生产 Jenkinsfile
- `deploy/systemd/spacetimedb.service`
- `deploy/systemd/genarrative-api.service`
- `deploy/nginx/genarrative.conf`
- `deploy/nginx/snippets/genarrative-maintenance.conf`
- `deploy/env/api-server.env.example`
- `scripts/deploy/maintenance-on.sh`
- `scripts/deploy/maintenance-off.sh`
- `scripts/deploy/maintenance-status.sh`
- `scripts/build-production-release.sh`
- `scripts/jenkins-checkout-source.sh`
- `scripts/deploy/production-web-deploy.sh`
- `scripts/deploy/production-api-deploy.sh`
- `scripts/deploy/production-stdb-publish.sh`
- `jenkins/Jenkinsfile.production-web-build`
- `jenkins/Jenkinsfile.production-web-deploy`
- `jenkins/Jenkinsfile.production-api-build`
- `jenkins/Jenkinsfile.production-api-deploy`
- `jenkins/Jenkinsfile.production-stdb-module-build`
- `jenkins/Jenkinsfile.production-stdb-module-publish`
- `jenkins/Jenkinsfile.production-full-build-and-deploy`
- `jenkins/Jenkinsfile.production-server-provision`
- `jenkins/Jenkinsfile.production-database-export`
- `jenkins/Jenkinsfile.production-database-import`
- `npm run build:production-release`
旧 Jenkins 一体化发布链对应的 Jenkinsfile 已从仓库移除,生产构建和发布入口统一切到 `jenkins/Jenkinsfile.production-*``scripts/deploy-rust-remote.sh` 等旧发布包脚本暂保留为历史迁移参考,不再作为生产 Jenkins Job 的入口。
## 目标
将当前部署方式调整为单机生产推荐方案:生产运行路径不使用 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。
- 静态资源仍允许访问,避免维护页样式和资源加载失败。
- 发布成功后自动解除维护模式。
- 发布失败时保持维护模式,并通过邮件通知人工处理。
## 构建产物
生产发布包构建入口:
```bash
npm run build:production-release -- --name <version>
```
每次构建产物按版本号归档:
```text
build/<version>/
├─ web/
│ ├─ index.html
│ ├─ assets/
│ ├─ maintenance.html
│ └─ admin/
├─ web.tar.gz
├─ web.tar.gz.sha256
├─ api-server
├─ api-server.sha256
├─ spacetime_module.wasm
├─ spacetime_module.wasm.sha256
├─ release-manifest.json
├─ scripts/
│ ├─ database-export.mjs
│ ├─ database-import.mjs
│ ├─ spacetime-migration-common.mjs
│ ├─ maintenance-on.sh
│ ├─ maintenance-off.sh
│ └─ maintenance-status.sh
├─ deploy/
│ ├─ systemd/
│ │ ├─ spacetimedb.service
│ │ └─ genarrative-api.service
│ ├─ nginx/
│ │ ├─ genarrative.conf
│ │ └─ snippets/genarrative-maintenance.conf
│ └─ env/api-server.env.example
└─ README.md
```
`web/` 可以保留在构建目录中供本地 smoke test 与人工排查使用,但 Jenkins Web Build 归档和 Web Deploy 传输必须以 `web.tar.gz` 为主,避免把大量静态碎文件逐个传回 Jenkins controller。`api-server``spacetime_module.wasm` 是单文件产物,默认直接归档单文件与对应 `.sha256`,不强制压缩。
不再生成旧产物:
- `web-server.mjs`
- 旧的一体化 `start.sh`
- 旧的一体化 `stop.sh`
## Jenkins 节点
Jenkins 可运行在 Windows 或其他机器上,本机 Windows 只作为人工触发入口;构建与发布动作只允许由 Jenkins 调度到 Linux agent 执行。当前已接入的 Linux agent 是开发/构建机,同时也是 development 环境部署机。
### 开发/构建/开发部署实例
- Jenkins Job 参数不暴露真实节点名、IP 或带 IP 的标签。
- 构建 Job 固定使用 label expression`linux && genarrative-build`
- 当前开发/构建/开发部署 agent 必须同时配置 `linux``genarrative-build` 两个标签;非 Linux 节点不能承担构建或部署。
- 用途:拉代码、安装依赖、构建主站、构建后台、构建 `api-server`、构建 SpacetimeDB wasm、归档产物并执行 `DEPLOY_TARGET=development` 的开发环境部署。
### 生产/发布实例
- Jenkins Job 参数不暴露真实节点名、IP 或带 IP 的标签。
- 生产机已作为独立 Linux Jenkins agent 接入,节点名使用脱敏名称 `genarrative-release-deploy-01`,调度标签只使用 `linux``genarrative-release-deploy`
- 生产机真实连接地址只允许保存在 Jenkins 节点 SSH launcher 的 `host` 字段中不能写入节点名、调度标签、Job 参数默认值或文档推荐命令。
- 发布 Job 通过 `DEPLOY_TARGET` 选择逻辑部署目标,再在 Jenkinsfile 内部映射到 Linux-only 脱敏调度表达式:`development -> linux && genarrative-build``release -> linux && genarrative-release-deploy`
- 用途:服务器配置、发布静态网站、发布 `api-server`、发布 SpacetimeDB 模块、数据库导入导出、维护模式切换。
### Git 仓库访问
Jenkins controller 与 Linux agent 看到的 Git 服务地址不同,必须拆成两层配置:
- Jenkins Job 的 `Pipeline script from SCM` 由 controller 执行SCM URL 使用 controller 可访问的公网地址:`http://82.157.175.59:3000/GenarrativeAI/Genarrative.git`
- Jenkinsfile 内部的源码、脚本 checkout 在 Linux agent 上执行,`GIT_REMOTE_URL` 使用 agent 本机可访问地址:`http://127.0.0.1:3000/GenarrativeAI/Genarrative.git`
因此生产 Jenkinsfile 不使用 `checkout scm` 作为构建源码入口,而是显式 `checkout([$class: 'GitSCM', userRemoteConfigs: [[url: "${GIT_REMOTE_URL}"]], ...])`。后续 `scripts/jenkins-checkout-source.sh` 会继续把 `origin` 设置为 `GIT_REMOTE_URL`,并按 `SOURCE_BRANCH` / `COMMIT_HASH` 拉取和校验目标提交。
`127.0.0.1` 只代表当前执行该阶段的 Linux agent 自身;如果 release agent 与 Git 服务不在同一台机器,必须把对应 Jenkinsfile 的 `GIT_REMOTE_URL` 改成 release agent 可访问的内网地址,不能让 release 发布阶段回退到 controller 公网拉取。
### SSH PEM 凭证
在 Jenkins 中使用 `SSH Username with private key` 类型添加 PEM 私钥:
- `genarrative-dev-ssh-key`:开发/构建实例 SSH 凭证。
- `genarrative-prod-root-ssh`:当前开发/构建实例已使用的 SSH 凭证;生产/发布实例复用同一个凭证。
推荐使用非 root 用户,例如 `jenkins`。该用户只通过 sudoers 获得必要命令权限,例如 `systemctl restart genarrative-api``nginx -t`、维护脚本、发布目录切换等。
## Jenkins 流水线
生产 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`
已落地的生产流水线脚本文件:
- `jenkins/Jenkinsfile.production-web-build`
- `jenkins/Jenkinsfile.production-web-deploy`
- `jenkins/Jenkinsfile.production-api-build`
- `jenkins/Jenkinsfile.production-api-deploy`
- `jenkins/Jenkinsfile.production-stdb-module-build`
- `jenkins/Jenkinsfile.production-stdb-module-publish`
- `jenkins/Jenkinsfile.production-full-build-and-deploy`
- `jenkins/Jenkinsfile.production-server-provision`
- `jenkins/Jenkinsfile.production-database-export`
- `jenkins/Jenkinsfile.production-database-import`
`Genarrative-Database-Export``Genarrative-Database-Import` 的生产版 Jenkinsfile 已落地;旧的数据库导入导出 Jenkinsfile 已删除,避免继续沿用旧部署目录和旧一体化发布链假设。
构建流水线运行在当前 Linux agent 的脱敏 label expression `linux && genarrative-build`。发布、导入导出和服务器配置流水线通过 `DEPLOY_TARGET` 映射到 Linux-only 脱敏部署表达式;其中 `development` 映射到当前 Linux 开发/构建/开发部署 agent 的 `linux && genarrative-build``release` 映射到独立 Linux 生产部署 agent 的 `linux && genarrative-release-deploy`,不能复用当前开发/构建/开发部署 agent。真实机器名、IP 和带 IP 的 Jenkins label 只允许留在 Jenkins 节点连接配置中,不能暴露为 Job 参数默认值、调度标签或文档推荐值。
发布流水线通过 Jenkins `copyArtifacts(...)` 从对应构建 Job 获取归档产物,因此 Jenkins 需要安装并启用 Copy Artifact 插件。数据库导入流水线的手动上传模式使用 `stashedFile` 文件参数,因此 Jenkins 还需要安装并启用 File Parameter 插件。生产发布不能退回到读取构建 workspace 本地目录的旧模式。
所有发布流水线必须提供 `DEPLOY_TARGET` 参数,用于选择逻辑部署目标:
- 默认值:`development`,用于当前 Linux 开发/构建/开发部署 agent 上的开发环境部署,对应脱敏调度表达式 `linux && genarrative-build`
- 备选值:`release`,对应生产发布目标,由独立 Linux 生产部署 agent 执行。
发布流水线的 `agent` 必须使用 `DEPLOY_TARGET` 在 Jenkinsfile 内部映射到脱敏 label expression并且表达式必须包含 `linux`避免在参数页面暴露真实节点名、IP 或带 IP 的 Jenkins label也避免非 Linux 节点执行构建或部署。`release` 目标还必须要求 `CONFIRM_RELEASE_DEPLOY_AGENT=true``Genarrative-Full-Build-And-Deploy` 也必须透传同一个 `DEPLOY_TARGET`,确保 Stdb publish、API deploy、Web deploy 三个部署动作落到同一类目标部署环境。
### Rust 构建缓存与磁盘控制
Jenkins 在 agent 上执行构建时会为不同 Job 或不同构建创建独立 workspaceRust 默认把编译产物写入仓库内 `server-rs/target/`,会导致每个 workspace 都保留一份完整 target 目录,占用大量磁盘。生产构建流水线必须把 Rust 缓存固定到 workspace 外的稳定目录。
如果构建 agent 使用 `root` 账户执行,缓存目录不应写死为 `/var/lib/jenkins`。推荐优先使用单独数据盘,例如 `/data/jenkins-cache/genarrative/`;如果没有数据盘,可使用 `/var/cache/genarrative-build/`
```bash
mkdir -p /var/cache/genarrative-build/{cargo-home,cargo-target,sccache}
chmod 700 /var/cache/genarrative-build
```
Rust 构建流水线建议统一设置:
```groovy
environment {
CARGO_HOME = '/var/cache/genarrative-build/cargo-home'
CARGO_TARGET_DIR = '/var/cache/genarrative-build/cargo-target/prod-release'
CARGO_INCREMENTAL = '0'
RUSTC_WRAPPER = 'sccache'
SCCACHE_DIR = '/var/cache/genarrative-build/sccache'
SCCACHE_CACHE_SIZE = '30G'
}
```
如使用数据盘,则把上述路径替换为:
```groovy
environment {
CARGO_HOME = '/data/jenkins-cache/genarrative/cargo-home'
CARGO_TARGET_DIR = '/data/jenkins-cache/genarrative/cargo-target/prod-release'
CARGO_INCREMENTAL = '0'
RUSTC_WRAPPER = 'sccache'
SCCACHE_DIR = '/data/jenkins-cache/genarrative/sccache'
SCCACHE_CACHE_SIZE = '30G'
}
```
`scripts/build-production-release.sh` 必须尊重 `CARGO_TARGET_DIR`,不能硬编码从 `server-rs/target/` 拷贝 Rust 产物。脚本中的产物路径应按以下口径计算:
```bash
CARGO_TARGET_DIR="${CARGO_TARGET_DIR:-${SERVER_RS_DIR}/target}"
API_BINARY_SOURCE="${CARGO_TARGET_DIR}/x86_64-unknown-linux-gnu/release/api-server"
WASM_SOURCE="${CARGO_TARGET_DIR}/wasm32-unknown-unknown/release/spacetime_module.wasm"
```
并发与清理规则:
- Rust 构建 Job 建议使用 `disableConcurrentBuilds()`,或对共享 `CARGO_TARGET_DIR` 加 Jenkins `lock`,避免多个同包 release 构建同时写入同一最终产物路径。
- 生产发布流水线只能消费 `build/<version>/` 或 Jenkins 归档产物,不允许从共享 `cargo-target` 目录直接发布。
- `SCCACHE_CACHE_SIZE` 必须设置上限,避免编译缓存无限增长。
-`/var/cache/genarrative-build/cargo-target` 或数据盘对应目录配置定期清理,建议保留最近 14 到 30 天。
- Jenkins Job 必须配置构建记录和归档产物保留策略,避免历史 release 包长期堆积。
### 统一源码版本参数
所有构建流水线、发布流水线和 `Genarrative-Full-Build-And-Deploy` 都必须支持以下参数:
- `SOURCE_BRANCH`:源码分支,默认 `master`,代表 `origin/master` 最新提交。
- `COMMIT_HASH`:可选 Git commit hash留空时使用 `origin/<SOURCE_BRANCH>` 最新 commit填写时必须是 7 到 40 位十六进制 hash并且该 commit 必须属于 `origin/<SOURCE_BRANCH>`
- `DEPLOY_TARGET`:逻辑部署目标选择参数。发布流水线和 `Genarrative-Full-Build-And-Deploy` 必填;构建流水线仅在 `PUBLISH_AFTER_BUILD=true` 时用于触发下游发布。
执行规则:
- 流水线先按 Jenkins SCM 配置 checkout 仓库,再执行 `git fetch --tags --prune origin "+refs/heads/<SOURCE_BRANCH>:refs/remotes/origin/<SOURCE_BRANCH>"`
- 如果工作区是浅克隆,流水线必须尝试 `git fetch --unshallow --tags`,确保能验证目标 commit 与分支关系。
- `COMMIT_HASH` 为空时detached checkout 到 `refs/remotes/origin/<SOURCE_BRANCH>` 当前最新 commit。
- `COMMIT_HASH` 非空时,先解析到完整 commit再用 `git merge-base --is-ancestor <commit> refs/remotes/origin/<SOURCE_BRANCH>` 校验该提交属于指定分支,校验通过后 detached checkout。
- 流水线日志必须输出最终 `SOURCE_BRANCH` 与实际 `SOURCE_COMMIT`
- 构建产物必须写入 `release-manifest.json`,至少包含 `version``source_branch``source_commit``built_at` 和组件类型,供发布、回滚和审计使用。
构建流水线使用上述参数决定实际构建源码。发布流水线也暴露同名参数,但只用于选择本次发布使用的部署脚本、配置模板和 smoke test 逻辑;被发布的应用文件仍必须来自 Jenkins 归档产物或指定 release 包,不允许在发布流水线中重新构建。
当构建流水线以 `PUBLISH_AFTER_BUILD=true` 触发下游发布流水线时,必须把 `SOURCE_BRANCH` 和实际解析出的 `SOURCE_COMMIT` 作为下游 `COMMIT_HASH` 传递,确保部署逻辑和刚生成的产物可追溯到同一源码版本。
构建流水线支持参数 `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`
该流水线属于高风险操作,默认要求人工确认后执行。
已落地的 Jenkinsfile 为 `jenkins/Jenkinsfile.production-server-provision`。该流水线默认 `DRY_RUN=true`只打印将执行的初始化动作真正写入系统用户、目录、systemd、Nginx 配置并启动服务时,必须设置 `DRY_RUN=false` 且勾选 `CONFIRM_PROVISION`。当 `DEPLOY_TARGET=release` 时,还必须勾选 `CONFIRM_RELEASE_DEPLOY_AGENT`,并通过 `linux && genarrative-release-deploy` 调度到独立 release 部署 agent。
### Web Build / Deploy
构建:
- 先按 `SOURCE_BRANCH` / `COMMIT_HASH` 解析并 checkout 目标源码,默认构建 `origin/master` 最新 commit。
- 构建主站静态文件。
- 构建后台前端base path 为 `/admin/`
- 生成或复制 `maintenance.html`
-`web/` 打包为 `web.tar.gz`,生成 `web.tar.gz.sha256`
- 归档 `web.tar.gz``web.tar.gz.sha256``release-manifest.json``web/` 展开目录不作为 Jenkins 主归档对象。
发布:
- 先按 `SOURCE_BRANCH` / `COMMIT_HASH` 解析并 checkout 部署脚本源码,默认使用 `origin/master` 最新 commit上游构建触发时使用上游传入的实际构建 commit。
- 获取 `web.tar.gz``web.tar.gz.sha256`,先校验 checksum再解压到 `/opt/genarrative/releases/<version>/web`
- 更新 `/opt/genarrative/current``/srv/genarrative/web` 指向。
- 执行 Nginx 配置测试和静态页面 smoke test。
- 不进入维护模式。
### Api Build / Deploy
构建:
- 先按 `SOURCE_BRANCH` / `COMMIT_HASH` 解析并 checkout 目标源码,默认构建 `origin/master` 最新 commit。
- 编译 Rust `api-server`
- 归档单一可执行文件、必要运行说明和 `release-manifest.json`
发布:
- 先按 `SOURCE_BRANCH` / `COMMIT_HASH` 解析并 checkout 部署脚本源码,默认使用 `origin/master` 最新 commit上游构建触发时使用上游传入的实际构建 commit。
- 进入维护模式。
- 解包到 `/opt/genarrative/releases/<version>/api-server`
- 更新 `/opt/genarrative/current`
- 重启 `genarrative-api.service`
- 检查本机 `/healthz`
- 导出产物归档成功后解除维护模式。
- 失败时保留维护模式并发邮件。
### Stdb Module Build / Publish
构建:
- 先按 `SOURCE_BRANCH` / `COMMIT_HASH` 解析并 checkout 目标源码,默认构建 `origin/master` 最新 commit。
- 使用 `spacetime build` 构建 `spacetime_module.wasm`
- 归档 wasm、发布脚本和 `release-manifest.json`
发布:
- 先按 `SOURCE_BRANCH` / `COMMIT_HASH` 解析并 checkout 发布脚本源码,默认使用 `origin/master` 最新 commit上游构建触发时使用上游传入的实际构建 commit。
- 进入维护模式。
- 将 wasm 上传到生产实例。
- 在生产实例本机执行 `spacetime publish -s local --bin-path spacetime_module.wasm <database-name>`
- 成功后执行必要 smoke test。
- 成功后解除维护模式。
- 失败时保留维护模式并发邮件。
### Full Build-And-Deploy
- 先解析一次最终 `SOURCE_COMMIT`,所有下游构建和发布都使用同一个分支与 commit。
- 并行执行 Web / API / Stdb 三条构建流水线。
- 构建全部成功后,按顺序执行 Stdb publish、API deploy、Web deploy并把同一个 `DEPLOY_TARGET` 透传给三条发布流水线。
- 每条下游构建都只消费自己的归档产物,不直接复用别的 workspace。
- 生产 Web 发布只处理 `web.tar.gz` 与 checksumAPI 发布只处理 `api-server` 与 checksumStdb 发布只处理 `spacetime_module.wasm` 与 checksum。
## 数据库导出与导入
### 导出
`Genarrative-Database-Export` 用于人工导出生产数据:
- 已落地 Jenkinsfile`jenkins/Jenkinsfile.production-database-export`
- 通过 `DEPLOY_TARGET` 选择逻辑导出目标;`development` 映射到 `linux && genarrative-build``release` 映射到 `linux && genarrative-release-deploy`
- `release` 导出必须勾选 `CONFIRM_RELEASE_DEPLOY_AGENT`,避免当前开发/构建/开发部署 agent 冒充 release 部署机。
- 进入维护模式,避免导出期间继续写入。
- 从目标机器本机 SpacetimeDB 导出指定数据库数据,默认连接 `SPACETIME_SERVER=local`,自托管 `root-dir` 默认 `/stdb`
- 产物归档到 Jenkins并可额外保存到 `SERVER_BACKUP_DIRECTORY`
- 敏感 token 与 bootstrap secret 只通过 Jenkins Secret Text 凭据 ID 注入,不作为明文 Job 参数。
- 成功后解除维护模式。
- 失败时保留维护模式并邮件通知。
### 导入
`Genarrative-Database-Import` 用于人工导入或恢复数据:
- 已落地 Jenkinsfile`jenkins/Jenkinsfile.production-database-import`
- 通过 `DEPLOY_TARGET` 选择逻辑导入目标;`development` 映射到 `linux && genarrative-build``release` 映射到 `linux && genarrative-release-deploy`
- `release` 导入必须勾选 `CONFIRM_RELEASE_DEPLOY_AGENT`,避免当前开发/构建/开发部署 agent 冒充 release 部署机。
- 通过 `INPUT_SOURCE` 选择数据源,`pipeline_archive``Genarrative-Database-Export` 归档复制 `INPUT_FILE``manual_upload` 使用本次构建上传的 `MANUAL_INPUT_FILE`;两种方式互斥,`Prepare` 阶段会直接拦截混填。
- `DRY_RUN` 默认开启;真正写入数据时必须勾选 `CONFIRM_IMPORT`,并让 `CONFIRM_DATABASE``CONFIRM_INPUT_FILE` 分别完全匹配 `DATABASE` 与实际输入文件。
- `REPLACE_EXISTING=true``DRY_RUN=false` 时必须额外勾选 `CONFIRM_REPLACE_EXISTING`
- 进入维护模式。
- 导入前先生成一次安全备份。
- 执行导入。
- 执行数据校验和服务 smoke test。
- 成功后解除维护模式。
- 失败时保留维护模式并邮件通知。
- `pipeline_archive` 模式默认使用导出流水线 `Genarrative-Database-Export`;只需要填写 `EXPORT_BUILD_NUMBER_TO_IMPORT` 时,归档输入路径自动解析为 `database-exports/spacetime-migration-<导出构建号>.json`。如果导出时覆盖过 `WORKSPACE_EXPORT_DIRECTORY``EXPORT_NAME`,再显式填写归档内相对路径 `INPUT_FILE`
- `manual_upload` 模式需要上传 `MANUAL_INPUT_FILE`,并在 `CONFIRM_INPUT_FILE` 中填写原始文件名;此模式不再填写 `EXPORT_BUILD_NUMBER_TO_IMPORT``INPUT_FILE``EXPORT_JOB_NAME` 的默认值会被忽略。
- 敏感 token 与 bootstrap secret 只通过 Jenkins Secret Text 凭据 ID 注入,不作为明文 Job 参数。
数据库表结构变更必须同步检查并更新 `migration.rs`,不能只发布 wasm。
## 全量构建并发布
`Genarrative-Full-Build-And-Deploy` 编排:
1.`SOURCE_BRANCH` / `COMMIT_HASH` 解析一次最终 `SOURCE_COMMIT`,默认 `origin/master` 最新 commit。
2. 并行触发 `Genarrative-Web-Build``Genarrative-Api-Build``Genarrative-Stdb-Module-Build`,三条构建都必须使用同一个 `SOURCE_BRANCH``SOURCE_COMMIT`
3. 三条构建全部成功后,按顺序触发 `Genarrative-Stdb-Module-Publish``Genarrative-Api-Deploy``Genarrative-Web-Deploy`,同样继续透传同一个 `SOURCE_BRANCH``SOURCE_COMMIT``DEPLOY_TARGET`
4. 最后执行生产 smoke test。
网站最后发布,避免后台或主站提前指向尚未完成发布的后端能力。
这种编排能够在不牺牲版本一致性的前提下缩短总耗时,同时避免 Web / API / Stdb 彼此等待构建资源。并行构建时仍要保证每条构建流水线独立归档自己的产物,发布阶段只能消费归档结果,不能回到构建 workspace 重新取文件。
`Genarrative-Full-Build-And-Deploy` 额外作为定时任务运行Jenkins 在每天凌晨 4 点自动触发一次,默认按 `SOURCE_BRANCH=master` 解析最新提交,并以 `DEPLOY_TARGET=development` 把全量构建结果部署到开发机。该定时任务不改写手动触发参数语义,只是给主线全量发布补一个固定的夜间全量刷新入口。
## 回滚
- 网站回滚:将 `/srv/genarrative/web``/opt/genarrative/current` 切回上一版本并 reload Nginx。
- `api-server` 回滚:将 `/opt/genarrative/current` 切回上一版本并重启 `genarrative-api.service`
- SpacetimeDB 模块回滚:发布上一版本 `spacetime_module.wasm`
- 数据回滚:使用导入流水线恢复指定备份,必须进入维护模式。
## 待落地文件
后续工程落地时需要新增或改造:
- [x] `deploy/systemd/spacetimedb.service`
- [x] `deploy/systemd/genarrative-api.service`
- [x] `deploy/nginx/genarrative.conf`
- [x] `deploy/nginx/snippets/genarrative-maintenance.conf`
- [x] `deploy/env/api-server.env.example`
- [x] `scripts/deploy/maintenance-on.sh`
- [x] `scripts/deploy/maintenance-off.sh`
- [x] `scripts/deploy/maintenance-status.sh`
- [x] `scripts/build-production-release.sh`
- [x] `scripts/jenkins-checkout-source.sh`
- [x] `scripts/deploy/production-web-deploy.sh`
- [x] `scripts/deploy/production-api-deploy.sh`
- [x] `scripts/deploy/production-stdb-publish.sh`
- [x] `jenkins/Jenkinsfile.production-web-build`
- [x] `jenkins/Jenkinsfile.production-web-deploy`
- [x] `jenkins/Jenkinsfile.production-api-build`
- [x] `jenkins/Jenkinsfile.production-api-deploy`
- [x] `jenkins/Jenkinsfile.production-stdb-module-build`
- [x] `jenkins/Jenkinsfile.production-stdb-module-publish`
- [x] `jenkins/Jenkinsfile.production-full-build-and-deploy`
- [x] `jenkins/Jenkinsfile.production-server-provision`
- [x] 删除旧 Jenkinsfile`Jenkinsfile.build-and-deploy``Jenkinsfile.deploy``Jenkinsfile.database-export``Jenkinsfile.database-import`
- [x] 更新旧部署文档,标记旧一体化脚本为废弃或迁移对象。
- [x] `jenkins/Jenkinsfile.production-database-export`
- [x] `jenkins/Jenkinsfile.production-database-import`
## 参考
- SpacetimeDB 官方自托管文档https://spacetimedb.com/docs/how-to/deploy/self-hosting/
- 该文档建议 Ubuntu 24.04、`spacetimedb` 专用用户、`/stdb` root-dir、systemd 托管,以及 Nginx/HTTPS。
- 默认公网路由只开放 TypeScript SDK 必需的 `/v1/identity``/v1/database/<database>/subscribe`其他发布、SQL、管理类入口保持本机可用。

View File

@@ -5,6 +5,7 @@
## 文档列表
- [PRODUCT_NAMING_BAIMENG_RENAME_2026-05-01.md](./PRODUCT_NAMING_BAIMENG_RENAME_2026-05-01.md):冻结当前对外中文命名,产品展示名统一为“百梦”,消费单位为“光点”,公开账号标识为“百梦号”,创作侧称谓为“百梦主”。
- [PRODUCTION_DEPLOYMENT_PLAN_2026-05-02.md](./PRODUCTION_DEPLOYMENT_PLAN_2026-05-02.md):冻结单机生产部署目标,从旧一体化启动脚本切到 Nginx、systemd 托管 SpacetimeDB 与 Rust `api-server`,并记录生产 Jenkins 流水线拆分计划和首批部署骨架。
- [SPACETIMEDB_SCHEMA_CHANGE_CONSTRAINTS.md](./SPACETIMEDB_SCHEMA_CHANGE_CONSTRAINTS.md):冻结 SpacetimeDB 表结构变更约束、自动迁移可接受范围、冲突后的系统行为,以及保留旧数据的增量迁移流程;凡涉及 `spacetime publish`、表字段调整或 `migration.rs` 对齐时优先参考。
- [SPACETIMEDB_LOCAL_REPLICA_IDENTITY_MISMATCH_FIX_2026-04-30.md](./SPACETIMEDB_LOCAL_REPLICA_IDENTITY_MISMATCH_FIX_2026-04-30.md):记录本地 standalone 启动时报 `mismatched database identity` 的 root-dir/replica 数据残留根因、备份重建步骤和脚本诊断口径。
- [AUTH_SNAPSHOT_AND_MATCH3D_LOCAL_DEV_FIX_2026-05-01.md](./AUTH_SNAPSHOT_AND_MATCH3D_LOCAL_DEV_FIX_2026-05-01.md):记录 Maincloud `xushi-p4wfr` 挂起导致认证快照同步和抓大鹅创作失败的根因、认证同步非阻断修复、`/api/creation` Vite 代理补齐和本地 SpacetimeDB 可跑链路。
@@ -19,7 +20,7 @@
- [MATCH3D_Q1_INTEGRATION_ACCEPTANCE_2026-05-01.md](./MATCH3D_Q1_INTEGRATION_ACCEPTANCE_2026-05-01.md):记录抓大鹅 Match3D 第一至第三波完成度复核、Q1 主链集成落点、定向验收命令和遗留风险。
- [PLATFORM_MOBILE_BOTTOM_DOCK_VIEWPORT_FIX_2026-04-30.md](./PLATFORM_MOBILE_BOTTOM_DOCK_VIEWPORT_FIX_2026-04-30.md):记录平台首页底部 dock 在手机浏览器地址栏展开时脱离可见区域的根因,以及 `100dvh`、固定底部锚点和安全区占位的修复口径。
- [SPACETIMEDB_JSON_STRING_MIGRATION_PROCEDURE_2026-04-27.md](./SPACETIMEDB_JSON_STRING_MIGRATION_PROCEDURE_2026-04-27.md):记录 SpacetimeDB private 表迁移 JSON 导出/导入 procedure、迁移操作员授权、HTTP 413 分片导入、Jenkins 自动迁移回灌和导入脚本参数。
- [JENKINS_SPACETIMEDB_DATABASE_MIGRATION_PIPELINES_2026-04-29.md](./JENKINS_SPACETIMEDB_DATABASE_MIGRATION_PIPELINES_2026-04-29.md)记录 `Genarrative-Database-Export` / `Genarrative-Database-Import` 两条 SCM-backed 数据库迁移流水线参数、默认 dry-run、token 边界和 `CHUNK_SIZE` 413 规避参数
- [JENKINS_SPACETIMEDB_DATABASE_MIGRATION_PIPELINES_2026-04-29.md](./JENKINS_SPACETIMEDB_DATABASE_MIGRATION_PIPELINES_2026-04-29.md)历史记录,保留 `Genarrative-Database-Export` / `Genarrative-Database-Import` 迁移参数、默认 dry-run、token 边界和 `CHUNK_SIZE` 413 规避经验;旧 Jenkinsfile 已删除,生产版入口以 `PRODUCTION_DEPLOYMENT_PLAN_2026-05-02.md` 为准
- [ADMIN_WEB_CONSOLE_TECHNICAL_SOLUTION_2026-04-30.md](./ADMIN_WEB_CONSOLE_TECHNICAL_SOLUTION_2026-04-30.md):冻结后台管理独立前端工程 `apps/admin-web` 的技术方案,明确管理端只做表现、全部数据和写操作走 `server-rs``/admin/api/*`,并接管旧 `GET /admin` 内嵌页面的 UI 职责。
- [RPG_PROMPT_FRONTEND_REMOVAL_AND_SERVER_RS_MIGRATION_2026-04-28.md](./RPG_PROMPT_FRONTEND_REMOVAL_AND_SERVER_RS_MIGRATION_2026-04-28.md):冻结 RPG 提示词禁止存在前端的边界,明确前端只保留 API client角色私聊/NPC 对话/剧情续写等 prompt 统一收口到 `server-rs`
- [RPG_CREATION_RESULT_VIEW_BACKEND_TRUTH_MIGRATION_2026-04-28.md](./RPG_CREATION_RESULT_VIEW_BACKEND_TRUTH_MIGRATION_2026-04-28.md):冻结 RPG 创作结果页保存、Agent session/result preview 真相优先级和结果页入口裁决迁移到后端 result-view 的落地边界。
@@ -82,9 +83,9 @@
- [CREATION_AGENT_PUBLISH_GATE_SCHEMA_ALIGNMENT_FIX_2026-04-23.md](./CREATION_AGENT_PUBLISH_GATE_SCHEMA_ALIGNMENT_FIX_2026-04-23.md):记录发布阻断项仍按旧 `worldHook / playerPremise / sceneChapters` schema 校验的问题,以及将 Rust `publish gate` 对齐到 `anchorContent / creatorIntent / sceneChapterBlueprints` 当前主链结构的修复口径。
- [CREATION_HUB_CARD_ACTIONS_2026-04-22.md](./CREATION_HUB_CARD_ACTIONS_2026-04-22.md):冻结创作中心作品卡“体验 / 删除”入口的最小落地语义,明确 RPG 已发布作品软删除、卡片直达运行时,以及暂不扩草稿 / 拼图删除契约。
- [CREATION_CATEGORY_OPENING_TIMEOUT_GUARD_FIX_2026-04-22.md](./CREATION_CATEGORY_OPENING_TIMEOUT_GUARD_FIX_2026-04-22.md):记录创作中心点击类别后长时间停留在“正在开启”的根因与修复口径,收口前端创建会话启动超时、中文错误提示以及 Big Fish / 拼图代理上游超时兜底。
- [JENKINS_RUST_BUILD_DEPLOY_PIPELINES_2026-04-23.md](./JENKINS_RUST_BUILD_DEPLOY_PIPELINES_2026-04-23.md)冻结 Jenkins `构建 / 部署 / 构建并部署` 三条流水线的职责、版本号传递、上游触发门禁、本地目录部署脚本、发布包覆盖策略,以及部署阶段 SpacetimeDB schema 冲突自动导出、清库发布、导入回灌能力
- [JENKINS_RUST_BUILD_DEPLOY_PIPELINES_2026-04-23.md](./JENKINS_RUST_BUILD_DEPLOY_PIPELINES_2026-04-23.md)历史记录,保留旧 Jenkins `构建 / 部署 / 构建并部署` 三条流水线的职责、版本号传递、上游触发门禁、本地目录部署脚本、发布包覆盖策略,以及部署阶段 SpacetimeDB schema 冲突自动导出、清库发布、导入回灌经验;旧 Jenkinsfile 已删除,生产版入口以 `PRODUCTION_DEPLOYMENT_PLAN_2026-05-02.md` 为准
- [JENKINS_DEPLOY_ENV_BOM_FIX_2026-04-25.md](./JENKINS_DEPLOY_ENV_BOM_FIX_2026-04-25.md):记录 Jenkins 部署时 `.env.local` 首行 UTF-8 BOM 导致 `start.sh` 加载失败的根因,并冻结发布包构建、部署脚本和启动脚本的环境文件净化规则。
- [RUST_LOCAL_AND_REMOTE_DEPLOYMENT_SCRIPTS_2026-04-22.md](./RUST_LOCAL_AND_REMOTE_DEPLOYMENT_SCRIPTS_2026-04-22.md)冻结 Rust 本地一键联调脚本与 Ubuntu 发布包构建脚本的执行口径,覆盖 `npm run dev:rust``npm run build:rust:ubuntu`、Vite release、Linux `api-server`、SpacetimeDB wasm、启动停止脚本、默认 scp 上传、安全清库开关,以及发布包内 schema 冲突自动迁移脚本
- [RUST_LOCAL_AND_REMOTE_DEPLOYMENT_SCRIPTS_2026-04-22.md](./RUST_LOCAL_AND_REMOTE_DEPLOYMENT_SCRIPTS_2026-04-22.md)历史记录,保留 Rust 本地一键联调脚本与 Ubuntu 发布包构建脚本的执行口径;生产发布链路以 `PRODUCTION_DEPLOYMENT_PLAN_2026-05-02.md` 的 systemd、Nginx、生产 Jenkinsfile 与归档产物拆分为准
- [RUST_API_SERVER_ROUTE_INDEX_2026-04-22.md](./RUST_API_SERVER_ROUTE_INDEX_2026-04-22.md):记录当前 Rust `api-server` 已挂载的 Axum 路由,并补充管理 API 索引,按 auth、assets、runtime、custom world、story、generated path 等挂载面归类,用于对照 Node 能力基线与切流 smoke 清单。
- [BACKEND_REWRITE_CROSS_CUTTING_GOVERNANCE_2026-04-22.md](./BACKEND_REWRITE_CROSS_CUTTING_GOVERNANCE_2026-04-22.md):冻结后端重写收口阶段的横向治理规则,覆盖 TypeScript contract 到 Rust DTO 映射、SpacetimeDB schema 演进、大对象 / workflow cache 存储边界和文档维护门禁。
- [PLATFORM_LLM_TEXT_GATEWAY_DESIGN_2026-04-21.md](./PLATFORM_LLM_TEXT_GATEWAY_DESIGN_2026-04-21.md)`platform-llm` 文本模型网关首版设计,冻结 OpenAI 兼容 `/chat/completions`、SSE 增量解析、错误模型与重试边界。
@@ -208,11 +209,11 @@
- [AI_CHARACTER_ANIMATION_TECHNICAL_SOLUTION_2026-04-04.md](./AI_CHARACTER_ANIMATION_TECHNICAL_SOLUTION_2026-04-04.md)AI 生成角色形象与角色动画的技术路线。
- [ALIYUN_NPC_IMAGE_ANIMATION_EXPERIMENT_2026-04-07.md](./ALIYUN_NPC_IMAGE_ANIMATION_EXPERIMENT_2026-04-07.md):面向编辑器的阿里云 NPC 形象与动作实验方案,按 4 条生成链路对比。
- [PIXELMOTION_TECHNICAL_BREAKDOWN_2026-04-04.md](./PIXELMOTION_TECHNICAL_BREAKDOWN_2026-04-04.md)PixelMotion 产品形态与能力拆解。
- [SERVER_DEPLOYMENT_AND_CORS_TECHNICAL_SOLUTION_2026-04-05.md](./SERVER_DEPLOYMENT_AND_CORS_TECHNICAL_SOLUTION_2026-04-05.md):服务端部署、代理层与 CORS 方案。
- [SERVER_DEPLOYMENT_AND_CORS_TECHNICAL_SOLUTION_2026-04-05.md](./SERVER_DEPLOYMENT_AND_CORS_TECHNICAL_SOLUTION_2026-04-05.md)服务端部署、代理层与 CORS 方案,保留同源代理和密钥不进前端的背景判断;当前生产拓扑和发布入口以 `PRODUCTION_DEPLOYMENT_PLAN_2026-05-02.md` 为准
- [WORLD_DRAFT_FOUNDATION_EDITOR_TARGET_FIX_2026-04-25.md](./WORLD_DRAFT_FOUNDATION_EDITOR_TARGET_FIX_2026-04-25.md):记录世界草稿“基本设定”独立编辑目标、分号标签化展示与编辑回写边界。
## 使用建议
- 做实现选型时,优先看这一组。
- 做实现选型时,优先看这一组做生产发布、服务器配置、Jenkins Job 重建或回滚时,先看 `PRODUCTION_DEPLOYMENT_PLAN_2026-05-02.md`,再按需追溯旧 Jenkins / CORS / 本地发布脚本文档
- 做后端实现前,先看 `CURRENT_BACKEND_IMPLEMENTATION_BASELINE_2026-04-25.md`;涉及 SpacetimeDB 表结构、发布或迁移时,再看 `SPACETIMEDB_SCHEMA_CHANGE_CONSTRAINTS.md`,最后进入具体 Rust / SpacetimeDB 方案。
- 做阶段排期时,把这一组和 `docs/planning/``docs/prd/` 一起看,更容易判断先后顺序。

View File

@@ -2,6 +2,8 @@
日期:`2026-04-22`
状态:本地联调口径仍可参考;远端发布包和旧一体化启动脚本属于历史方案。生产发布、生产 Jenkins Job、systemd/Nginx 拓扑和 release/current 目录规则以 [PRODUCTION_DEPLOYMENT_PLAN_2026-05-02.md](./PRODUCTION_DEPLOYMENT_PLAN_2026-05-02.md) 为准。
## 1. 目标
本方案补齐 `server-rs` 在 M7 切流前需要的两类工程脚本:

View File

@@ -2,6 +2,8 @@
日期:`2026-04-05`
状态历史部署背景文档。本文保留同源代理、密钥不进入前端、CORS 不作为主解法等判断当前生产拓扑、systemd/Nginx 配置和 Jenkins 发布入口以 [PRODUCTION_DEPLOYMENT_PLAN_2026-05-02.md](./PRODUCTION_DEPLOYMENT_PLAN_2026-05-02.md) 为准。
## 1. 文档目标
本文要解决的不只是“当前部署到服务器后浏览器报 CORS”而是同时解决下面几类问题