Merge branch 'codex/backend-rewrite-spacetimedb' of http://82.157.175.59:3000/GenarrativeAI/Genarrative into codex/backend-rewrite-spacetimedb
This commit is contained in:
173
docs/technical/JENKINS_RUST_BUILD_DEPLOY_PIPELINES_2026-04-23.md
Normal file
173
docs/technical/JENKINS_RUST_BUILD_DEPLOY_PIPELINES_2026-04-23.md
Normal file
@@ -0,0 +1,173 @@
|
||||
# Jenkins Rust 构建与部署流水线方案
|
||||
|
||||
日期:`2026-04-23`
|
||||
|
||||
## 1. 目标
|
||||
|
||||
本方案为当前仓库补齐 3 条 Jenkins 流水线:
|
||||
|
||||
1. `构建`:只负责在仓库根目录执行 `npm run deploy:rust:remote -- --skip-upload`,生成发布包。
|
||||
2. `部署`:只负责把指定发布版本部署到 `/home/ubuntu/Genarrative-deploy/`,禁止人工直接点击执行。
|
||||
3. `构建并部署`:先构建,再把构建出的版本号传给 `部署` 流水线并等待部署完成。
|
||||
|
||||
本次只补 Jenkins 编排与本地部署脚本,不改现有 Rust 发布包构建逻辑,不恢复旧 `server-node` 部署链。
|
||||
|
||||
## 2. 执行约束
|
||||
|
||||
1. 构建产物目录统一使用 `build/<版本号>/`。
|
||||
2. 默认使用 Jenkins `BUILD_NUMBER` 作为版本号,避免依赖时间戳;如有需要也允许显式传 `BUILD_VERSION`。
|
||||
3. `部署` 流水线必须校验当前构建原因包含 `UpstreamCause`,没有上游触发则直接失败。
|
||||
4. `部署` 流水线额外校验上游作业名与传入的 `EXPECTED_UPSTREAM_JOB` 一致;如配置了环境变量 `GENARRATIVE_ALLOWED_UPSTREAM_JOB`,还必须与该值一致。
|
||||
5. `构建并部署` 在触发 `部署` 前先释放自己的构建节点,避免单执行器节点出现死锁。
|
||||
6. `部署` 不重新构建,不重新上传,不从 Jenkins 插件仓库复制产物,直接使用上游构建节点的本地 `build/<版本号>/` 目录。
|
||||
7. `部署` 流水线读取触发原因时必须使用 `currentBuild.getBuildCauses('hudson.model.Cause$UpstreamCause')` 这类白名单方法,不能直接访问 `currentBuild.rawBuild`,否则会被 Jenkins Script Security 拦截。
|
||||
|
||||
## 3. 节点与工作区要求
|
||||
|
||||
这套方案依赖“本地目录发布”,因此有两个前提:
|
||||
|
||||
1. `构建并部署` 与 `部署` 必须落到同一台 Ubuntu Jenkins Agent,或者落到同一块共享文件系统。
|
||||
2. `构建并部署` 触发 `部署` 时,必须把 `SOURCE_NODE_NAME` 和 `SOURCE_WORKSPACE_ROOT` 一并传下去。
|
||||
|
||||
仓库中提供的 Jenkinsfile 已按这个约束实现:
|
||||
|
||||
1. `构建` / `构建并部署` 在指定源码目录内 `checkout scm` 并生成 `build/<版本号>/`。
|
||||
2. `构建并部署` 结束构建节点占用后,再触发 `部署`。
|
||||
3. `部署` 优先按 `SOURCE_NODE_NAME` 调度到同名节点,再读取 `SOURCE_WORKSPACE_ROOT/build/<版本号>/`。
|
||||
|
||||
## 4. 三条流水线定义
|
||||
|
||||
### 4.1 构建
|
||||
|
||||
脚本路径:
|
||||
|
||||
```text
|
||||
jenkins/Jenkinsfile.build
|
||||
```
|
||||
|
||||
核心流程:
|
||||
|
||||
1. 可选执行 `npm ci`。
|
||||
2. 在源码根目录执行:
|
||||
|
||||
```bash
|
||||
npm run deploy:rust:remote -- --skip-upload --name <BUILD_VERSION>
|
||||
```
|
||||
|
||||
3. 校验 `build/<BUILD_VERSION>/` 存在。
|
||||
4. 归档 `build/<BUILD_VERSION>/**` 作为 Jenkins 产物。
|
||||
|
||||
默认版本号:
|
||||
|
||||
```text
|
||||
BUILD_VERSION = Jenkins BUILD_NUMBER
|
||||
```
|
||||
|
||||
### 4.2 部署
|
||||
|
||||
脚本路径:
|
||||
|
||||
```text
|
||||
jenkins/Jenkinsfile.deploy
|
||||
```
|
||||
|
||||
核心流程:
|
||||
|
||||
1. 校验触发原因必须是上游流水线,而不是人工点击。
|
||||
2. 校验 `BUILD_VERSION`、`SOURCE_WORKSPACE_ROOT`、`DEPLOY_DIRECTORY` 非空。
|
||||
3. 执行:
|
||||
|
||||
```bash
|
||||
scripts/jenkins-deploy-release.sh \
|
||||
--source-dir <SOURCE_WORKSPACE_ROOT>/build/<BUILD_VERSION> \
|
||||
--deploy-dir /home/ubuntu/Genarrative-deploy
|
||||
```
|
||||
|
||||
脚本语义:
|
||||
|
||||
1. 若部署目录已有旧版本且存在 `stop.sh`,先执行旧版本 `stop.sh`。
|
||||
2. 直接清空部署目录中的全部旧文件。
|
||||
3. 将指定版本目录中的内容移动到部署目录。
|
||||
4. 执行新版本 `start.sh`。
|
||||
|
||||
这样可以满足你要求的“直接覆盖部署目录中的所有文件”。同时这也意味着部署目录内原有的 `.env`、`.env.local`、日志和本地 SpacetimeDB 数据都会被清掉,最终以构建产物中的文件为准。
|
||||
|
||||
### 4.3 构建并部署
|
||||
|
||||
脚本路径:
|
||||
|
||||
```text
|
||||
jenkins/Jenkinsfile.build-and-deploy
|
||||
```
|
||||
|
||||
核心流程:
|
||||
|
||||
1. 复用与 `构建` 相同的构建命令生成 `build/<BUILD_VERSION>/`。
|
||||
2. 归档 `build/<BUILD_VERSION>/**`。
|
||||
3. 记录当前 `NODE_NAME`、源码根目录、版本号。
|
||||
4. 触发 `部署` 流水线,并传递:
|
||||
- `BUILD_VERSION`
|
||||
- `SOURCE_WORKSPACE_ROOT`
|
||||
- `SOURCE_NODE_NAME`
|
||||
- `DEPLOY_DIRECTORY`
|
||||
- `EXPECTED_UPSTREAM_JOB`
|
||||
|
||||
## 5. Jenkins 参数建议
|
||||
|
||||
三条流水线统一建议暴露以下参数:
|
||||
|
||||
1. `AGENT_LABEL`:默认执行节点标签。
|
||||
2. `GENARRATIVE_WORKSPACE_ROOT`:源码根目录;为空时回退到 Jenkins 当前工作区。
|
||||
3. `BUILD_VERSION`:发布版本号;为空时回退到 `BUILD_NUMBER`。
|
||||
4. `RUN_NPM_CI`:是否在构建前执行 `npm ci`。
|
||||
|
||||
如果当前 Jenkins 没有额外配置独立 Agent,而是直接在控制器自身执行任务,`AGENT_LABEL` 应填写 `built-in`。
|
||||
如果目标 Ubuntu 的 Jenkins `sh` 默认实际落到 `/bin/sh -> dash`,而流水线脚本又使用了 `set -euo pipefail`,则必须显式通过 `bash -lc` 执行命令,不能直接依赖 Jenkins 默认 `sh` 解释器。
|
||||
|
||||
其中仅 `部署` 流水线还需要:
|
||||
|
||||
1. `SOURCE_WORKSPACE_ROOT`
|
||||
2. `SOURCE_NODE_NAME`
|
||||
3. `DEPLOY_DIRECTORY`
|
||||
4. `EXPECTED_UPSTREAM_JOB`
|
||||
|
||||
其中仅 `构建并部署` 流水线还需要:
|
||||
|
||||
1. `DEPLOY_JOB_NAME`
|
||||
|
||||
## 6. 推荐 Job 命名
|
||||
|
||||
建议在 Jenkins 中创建以下 3 个 Pipeline Job,并分别指向仓库中的脚本路径:
|
||||
|
||||
1. `Genarrative-Build` -> `jenkins/Jenkinsfile.build`
|
||||
2. `Genarrative-Deploy` -> `jenkins/Jenkinsfile.deploy`
|
||||
3. `Genarrative-Build-And-Deploy` -> `jenkins/Jenkinsfile.build-and-deploy`
|
||||
|
||||
同时给 `Genarrative-Deploy` 配置环境变量:
|
||||
|
||||
```text
|
||||
GENARRATIVE_ALLOWED_UPSTREAM_JOB=Genarrative-Build-And-Deploy
|
||||
```
|
||||
|
||||
如果 Job 在 Jenkins Folder 下,值应填写完整上游作业名,例如:
|
||||
|
||||
```text
|
||||
game/Genarrative-Build-And-Deploy
|
||||
```
|
||||
|
||||
## 7. 文件清单
|
||||
|
||||
本方案对应的仓库文件:
|
||||
|
||||
```text
|
||||
jenkins/Jenkinsfile.build
|
||||
jenkins/Jenkinsfile.deploy
|
||||
jenkins/Jenkinsfile.build-and-deploy
|
||||
scripts/jenkins-deploy-release.sh
|
||||
```
|
||||
|
||||
## 8. 风险与边界
|
||||
|
||||
1. 该方案依赖本地目录切换,不适用于“构建节点”和“部署节点”完全隔离且不共享文件系统的 Jenkins 架构。
|
||||
2. 当前 `部署` 采取的是“覆盖固定部署目录”的方式,不包含版本回滚目录管理;如需保留完整历史版本,应在后续单独补一层 release/current 软链接结构。
|
||||
3. 当前 `start.sh` / `stop.sh` 仍以发布包内脚本为准,不替代 `systemd`、`supervisor`、`nginx`、`tls` 与日志轮转治理。
|
||||
@@ -0,0 +1,163 @@
|
||||
# Axum 手机验证码真实短信 Provider 接入设计
|
||||
|
||||
日期:`2026-04-22`
|
||||
|
||||
## 1. 文档目的
|
||||
|
||||
这份文档用于冻结 Rust `api-server + module-auth + platform-auth` 切换到真实短信链路时的最小可编码边界,解决当前 `module-auth` 仍固定使用 mock 验证码 `123456`,导致 `server-rs` 无法接入真实短信发送与真实验证码校验的问题。
|
||||
|
||||
## 2. 当前问题
|
||||
|
||||
截至 `2026-04-22`,Rust 侧手机号登录存在以下状态:
|
||||
|
||||
1. `POST /api/auth/phone/send-code` 已存在,但 `module-auth` 内部仍写死 `123456`。
|
||||
2. `POST /api/auth/phone/login` 校验的是本地内存快照里的固定验证码,不是真实短信平台生成的验证码。
|
||||
3. 即使把发送动作切到真实阿里云短信,如果校验仍留在本地 mock,整条登录链仍然不可用。
|
||||
|
||||
## 3. 本次目标
|
||||
|
||||
本次必须达成:
|
||||
|
||||
1. Rust 侧短信 provider 支持 `mock` 与 `aliyun` 两种模式。
|
||||
2. `send-code` 在 `aliyun` 模式下调用阿里云 `SendSmsVerifyCode`。
|
||||
3. `phone/login` 与 `wechat/bind-phone` 在 `aliyun` 模式下调用阿里云 `CheckSmsVerifyCode`。
|
||||
4. `module-auth` 不再保存验证码明文,只保存发送冷却、有效期和失败次数所需的最小快照。
|
||||
5. `shared-contracts` 公开响应 contract 维持不变,仍只返回:
|
||||
- `ok`
|
||||
- `cooldownSeconds`
|
||||
- `expiresInSeconds`
|
||||
- `providerRequestId`
|
||||
|
||||
## 4. crate 边界
|
||||
|
||||
### 4.1 `platform-auth`
|
||||
|
||||
负责:
|
||||
|
||||
1. 短信 provider 配置结构。
|
||||
2. `mock / aliyun` provider 实现。
|
||||
3. 阿里云 RPC 请求签名、发送与校验。
|
||||
4. provider 级错误归一化。
|
||||
|
||||
### 4.2 `module-auth`
|
||||
|
||||
负责:
|
||||
|
||||
1. 手机号归一化。
|
||||
2. 发送冷却与验证码快照 TTL。
|
||||
3. 校验失败次数累加与耗尽删除。
|
||||
4. 手机号用户创建、复用、微信补绑归并。
|
||||
|
||||
### 4.3 `api-server`
|
||||
|
||||
负责:
|
||||
|
||||
1. 从环境变量读取短信 provider 配置。
|
||||
2. 构建 `SmsAuthProvider` 并注入 `PhoneAuthService`。
|
||||
3. 把领域错误映射成 HTTP 错误。
|
||||
|
||||
## 5. 配置设计
|
||||
|
||||
新增或继续使用以下环境变量:
|
||||
|
||||
1. `SMS_AUTH_ENABLED`
|
||||
2. `SMS_AUTH_PROVIDER`
|
||||
- `mock`
|
||||
- `aliyun`
|
||||
3. `ALIYUN_SMS_ENDPOINT`
|
||||
- 默认 `dypnsapi.aliyuncs.com`
|
||||
4. `ALIYUN_SMS_ACCESS_KEY_ID`
|
||||
5. `ALIYUN_SMS_ACCESS_KEY_SECRET`
|
||||
6. `ALIYUN_SMS_SIGN_NAME`
|
||||
7. `ALIYUN_SMS_TEMPLATE_CODE`
|
||||
8. `ALIYUN_SMS_TEMPLATE_PARAM_KEY`
|
||||
- 默认 `code`
|
||||
9. `ALIYUN_SMS_COUNTRY_CODE`
|
||||
- 默认 `86`
|
||||
10. `ALIYUN_SMS_SCHEME_NAME`
|
||||
11. `ALIYUN_SMS_CODE_LENGTH`
|
||||
- 默认 `6`
|
||||
12. `ALIYUN_SMS_CODE_TYPE`
|
||||
- 默认 `1`
|
||||
13. `ALIYUN_SMS_VALID_TIME_SECONDS`
|
||||
- 默认 `300`
|
||||
14. `ALIYUN_SMS_INTERVAL_SECONDS`
|
||||
- 默认 `60`
|
||||
15. `ALIYUN_SMS_DUPLICATE_POLICY`
|
||||
- 默认 `1`
|
||||
16. `ALIYUN_SMS_CASE_AUTH_POLICY`
|
||||
- 默认 `1`
|
||||
17. `ALIYUN_SMS_RETURN_VERIFY_CODE`
|
||||
- 默认 `false`
|
||||
18. `SMS_AUTH_MOCK_VERIFY_CODE`
|
||||
- 默认 `123456`
|
||||
|
||||
## 6. provider 行为
|
||||
|
||||
### 6.1 `mock`
|
||||
|
||||
1. 发送验证码时不访问外部网络。
|
||||
2. 返回固定 `mock-request-id`。
|
||||
3. 校验时使用内存中的 mock 验证码。
|
||||
|
||||
### 6.2 `aliyun`
|
||||
|
||||
1. 发送验证码调用 `SendSmsVerifyCode`。
|
||||
2. 校验验证码调用 `CheckSmsVerifyCode`。
|
||||
3. 使用阿里云 RPC 签名口径:
|
||||
- `SignatureMethod=HMAC-SHA1`
|
||||
- `SignatureVersion=1.0`
|
||||
4. 当前仍只支持中国大陆手机号。
|
||||
|
||||
## 7. 状态与快照
|
||||
|
||||
`module-auth` 内部验证码快照保留:
|
||||
|
||||
1. `phone_number`
|
||||
2. `scene`
|
||||
3. `expires_at`
|
||||
4. `last_sent_at`
|
||||
5. `failed_attempts`
|
||||
|
||||
明确不再保留:
|
||||
|
||||
1. 验证码明文
|
||||
2. 验证码 hash
|
||||
|
||||
校验流程改为:
|
||||
|
||||
1. 先检查是否存在活跃快照。
|
||||
2. 再检查是否过期。
|
||||
3. 再调用 provider 做真实验证码校验。
|
||||
4. 校验失败时累加失败次数。
|
||||
5. 达到上限时删除快照并返回 `429`。
|
||||
6. 校验成功后删除快照。
|
||||
|
||||
## 8. 错误语义
|
||||
|
||||
1. 手机号格式错误:`400`
|
||||
2. 验证码格式错误:`400`
|
||||
3. 验证码不存在或已过期:`400`
|
||||
4. 校验失败:`400`
|
||||
5. 验证码错误次数耗尽:`429`
|
||||
6. 阿里云配置缺失:`500`
|
||||
7. 阿里云上游失败:`502`
|
||||
|
||||
## 9. 测试要求
|
||||
|
||||
至少覆盖:
|
||||
|
||||
1. `mock` provider 的发送与登录仍可跑通。
|
||||
2. `aliyun` provider 缺配置时会在服务初始化阶段报错。
|
||||
3. 发送冷却逻辑不依赖验证码明文仍然有效。
|
||||
4. 校验失败次数耗尽后会删除快照。
|
||||
5. `send-code` 成功时仍返回既有 contract。
|
||||
|
||||
## 10. 非目标
|
||||
|
||||
本次明确不做:
|
||||
|
||||
1. 短信送达回执接口
|
||||
2. `sms_auth_event` 真实持久化
|
||||
3. 图形验证码
|
||||
4. 更细粒度的 provider 错误码透传 DTO
|
||||
@@ -7,6 +7,7 @@
|
||||
- [CUSTOM_WORLD_AGENT_LLM_REPLY_RESTORE_2026-04-22.md](./CUSTOM_WORLD_AGENT_LLM_REPLY_RESTORE_2026-04-22.md):恢复 Custom World Agent 聊天必须走大模型推理的 Rust 落地方案,冻结 submit/finalize 两阶段职责、旧 Node 提示词原样搬运、SSE 流式回复与 session 回写边界。
|
||||
- [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 `构建 / 部署 / 构建并部署` 三条流水线的职责、版本号传递、上游触发门禁、本地目录部署脚本与 `/home/ubuntu/Genarrative-deploy/` 覆盖策略。
|
||||
- [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 上传和安全清库开关。
|
||||
- [RUST_API_SERVER_ROUTE_INDEX_2026-04-22.md](./RUST_API_SERVER_ROUTE_INDEX_2026-04-22.md):记录当前 Rust `api-server` 已挂载的 96 条 Axum 路由,按 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 存储边界和文档维护门禁。
|
||||
@@ -19,6 +20,10 @@
|
||||
- [AUTH_SESSIONS_QUERY_DESIGN_2026-04-21.md](./AUTH_SESSIONS_QUERY_DESIGN_2026-04-21.md):`/api/auth/sessions` 会话列表设计,冻结当前设备识别、多端登录字段映射、`clientLabel` 兼容策略与 Rust 首版接口边界。
|
||||
- [PHONE_AUTH_AXUM_MINIMAL_FLOW_DESIGN_2026-04-21.md](./PHONE_AUTH_AXUM_MINIMAL_FLOW_DESIGN_2026-04-21.md):手机号验证码登录最小闭环设计,冻结 mock 验证码规则、`send-code` / `phone/login` contract 与 crate 边界。
|
||||
- [PHONE_AUTH_AXUM_RATE_LIMIT_AND_FAILURE_DESIGN_2026-04-21.md](./PHONE_AUTH_AXUM_RATE_LIMIT_AND_FAILURE_DESIGN_2026-04-21.md):手机号验证码冷却与失败次数限制设计,冻结同手机号同场景发送冷却、错误次数耗尽、`429` 与 `Retry-After` contract。
|
||||
- [PHONE_AUTH_AXUM_REAL_SMS_PROVIDER_DESIGN_2026-04-22.md](./PHONE_AUTH_AXUM_REAL_SMS_PROVIDER_DESIGN_2026-04-22.md):冻结 Rust `api-server + module-auth + platform-auth` 接入真实阿里云短信 provider 的 crate 边界、发送与校验职责、配置项和错误语义。
|
||||
- [PHONE_SMS_ALIYUN_RESPONSE_FIELD_MAPPING_FIX_2026-04-23.md](./PHONE_SMS_ALIYUN_RESPONSE_FIELD_MAPPING_FIX_2026-04-23.md):记录 Rust `platform-auth` 把阿里云 PascalCase 响应字段误判成空值的问题根因,并冻结字段映射修复与回归标准。
|
||||
- [PHONE_SMS_DELIVERY_OBSERVABILITY_AND_RECEIPT_DESIGN_2026-04-22.md](./PHONE_SMS_DELIVERY_OBSERVABILITY_AND_RECEIPT_DESIGN_2026-04-22.md):冻结短信平台受理成功与最终送达状态的区分方式、追踪字段、送达回执接口和前端提示文案边界。
|
||||
- [PHONE_SMS_REAL_PROVIDER_MANUAL_VERIFICATION_RUNBOOK_2026-04-23.md](./PHONE_SMS_REAL_PROVIDER_MANUAL_VERIFICATION_RUNBOOK_2026-04-23.md):冻结验证清单第一项“真实短信验证码链路”的本地启动、前端操作、日志观察点、通过标准与失败排查步骤。
|
||||
- [WECHAT_LOGIN_AXUM_IMPLEMENTATION_DESIGN_2026-04-21.md](./WECHAT_LOGIN_AXUM_IMPLEMENTATION_DESIGN_2026-04-21.md):Rust `api-server` 微信登录实现设计,冻结微信 provider 接入、系统 JWT 签发边界、`wechat/start` / `wechat/callback` / `wechat/bind-phone` 闭环,以及与后续 `SpacetimeDB` claims 透传的关系。
|
||||
- [WECHAT_LOGIN_REAL_INTEGRATION_RUNBOOK_2026-04-21.md](./WECHAT_LOGIN_REAL_INTEGRATION_RUNBOOK_2026-04-21.md):微信登录从本地 mock 到真实微信开放平台联调的执行手册,覆盖环境变量、回调域名、代理头要求、验证步骤与常见失败排查。
|
||||
- [PASSWORD_ENTRY_FLOW_DESIGN_2026-04-21.md](./PASSWORD_ENTRY_FLOW_DESIGN_2026-04-21.md):密码登录与自动建号落地设计,冻结 `/api/auth/entry`、幂等兼容策略、模块边界以及与 JWT / refresh cookie 的衔接方式。
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
本方案补齐 `server-rs` 在 M7 切流前需要的两类工程脚本:
|
||||
|
||||
1. 本地一键联调脚本:同时启动本地 SpacetimeDB、Rust `api-server` 与 Web 前端,并通过现有 Vite 代理开关把运行时 API 指向 Rust。
|
||||
2. Ubuntu 发布包构建脚本:在仓库根目录生成 `build/<当前时间>/` 发布目录,内含前端 release、Linux `api-server`、SpacetimeDB wasm、启动脚本与停止脚本,并默认通过 `scp` 上传到目标服务器。
|
||||
2. Ubuntu 发布包构建脚本:在仓库根目录生成 `build/<当前时间>/` 发布目录,内含前端 release、Linux `api-server`、SpacetimeDB wasm、启动脚本、停止脚本,以及从仓库根目录复制的 `.env` / `.env.local`,并默认通过 `scp` 上传到目标服务器。
|
||||
|
||||
脚本只做部署与联调编排,不改变 HTTP contract、SpacetimeDB schema 命名、对象存储键规划和前端默认 Node 开发入口。
|
||||
|
||||
@@ -102,15 +102,20 @@ npm run deploy:rust:remote
|
||||
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. 在目标目录写入 `web-server.mjs`,用于托管 `web/` 并把 `/api/*`、`/generated-*`、`/healthz` 反代到本包内的 `api-server`。
|
||||
7. 在目标目录写入 `start.sh` 与 `stop.sh`。
|
||||
8. 默认执行 `scp -r -i ~\.ssh\dsk.pem build/<timestamp> ubuntu@82.157.175.59:/home/ubuntu/genarrative/` 上传发布包。
|
||||
6. 把仓库根目录的 `.env` 与 `.env.local` 分别复制到目标目录根部和目标目录的 `web/` 下。
|
||||
7. 在目标目录写入 `web-server.mjs`,用于托管 `web/` 并把 `/api/*`、`/generated-*`、`/healthz` 反代到本包内的 `api-server`。
|
||||
8. 在目标目录写入 `start.sh` 与 `stop.sh`。
|
||||
9. 默认执行 `scp -r -i ~\.ssh\dsk.pem build/<timestamp> ubuntu@82.157.175.59:/home/ubuntu/genarrative/` 上传发布包。
|
||||
|
||||
发布包结构:
|
||||
|
||||
```text
|
||||
build/<timestamp>/
|
||||
├─ .env
|
||||
├─ .env.local
|
||||
├─ web/
|
||||
│ ├─ .env
|
||||
│ └─ .env.local
|
||||
├─ api-server
|
||||
├─ spacetime_module.wasm
|
||||
├─ web-server.mjs
|
||||
@@ -137,8 +142,8 @@ cd build/<timestamp>
|
||||
|
||||
安全边界:
|
||||
|
||||
1. 构建脚本不读取、不传输、不打印生产密钥。
|
||||
2. 目标服务器 `.env`、`.env.local` 或进程环境仍由服务器本身维护。
|
||||
1. 构建脚本会把仓库根目录已有的 `.env`、`.env.local` 一并复制进发布包,因此运行前必须确认这些文件内容适合被带入目标环境。
|
||||
2. 如果仓库根目录不存在 `.env` 或 `.env.local`,脚本会打印跳过日志,但不会因此失败。
|
||||
3. `start.sh` 默认不清空 SpacetimeDB;只有显式执行 `./start.sh --clear-database` 才允许清库重发。
|
||||
4. `start.sh` 使用 `spacetime publish --bin-path spacetime_module.wasm --yes` 发布当前包内 wasm。
|
||||
5. 当前脚本是单目录进程启动方案,不替代生产 systemd、Nginx、TLS、日志轮转与守护进程配置。
|
||||
|
||||
Reference in New Issue
Block a user