Files
ttstd-infinite-canvas/docs/content/docs/backend/system-update.mdx

85 lines
7.1 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: 在线更新与安全回退
description: Host Updater、Release 检查、数据库备份迁移、健康验证与异常回退机制。
---
# 在线更新与安全回退
管理后台的“系统配置 → 系统更新”只负责管理员鉴权、展示状态和发起操作。真正的 Docker、数据库备份与服务切换由宿主机上的 `open-ai-canvas-host-updater` 执行,业务后端不挂载 Docker Socket。
```text
管理员浏览器 → Backend 管理 API → 带 Token 的 Unix Socket → Host Updater → Docker Compose
```
## 安全更新顺序
1. 从 GitHub Releases 读取包含预览版在内的最高语义版本,并与 `.env` 中固定的 `CANVAS_IMAGE_TAG` 比较。`sha-*` 这类非正式镜像标签一律视为低于正式 Release,避免把 `vsha-5509b17` 字典序比较成比 `v1.5.0` 更新。
2. 下载目标版本的 `docker-compose.deploy.yml`,执行 `docker compose config --quiet`,检查部署文件、磁盘空间和当前版本。当前标签不是 `vX.Y.Z` 或 `vX.Y.Z.N` 时,健康检查只确认服务就绪,不要求构建号和镜像标签逐字相同。
3. 创建 `backup-YYYYMMDD-HHMMSS.zip.partial`,其中包含 PostgreSQL custom-format dump、后端数据目录 tar 和元数据;写入完成后 `fsync`、原子改名,并复核 ZIP 结构和 SHA-256。
4. 拉取目标 backend/web 镜像并要求存在仓库 `sha256` 摘要。任何失败都在停服前中止。
5. 停止 web/backend,等待 Backend 的 SIGTERM drain 完成;PostgreSQL 和 Redis 保持运行。
6. 用目标 backend 镜像独立执行 `migrate-schema up`。整批迁移在事务和 PostgreSQL advisory lock 内完成,迁移名称与 checksum 必须匹配。
7. 解析目标 backend/web 镜像的仓库 digest,原子更新 `CANVAS_IMAGE_TAG`、`CANVAS_BACKEND_IMAGE`、`CANVAS_WEB_IMAGE` 和 Compose 文件,启动目标版本;运行容器始终使用 `image@sha256:...`,不使用 `latest`。
8. 连续检查 `/api/health/ready` 的数据库、运行时、schema 和 build version,并经过稳定窗口后才标记成功。
更新状态写入 `/var/lib/open-ai-canvas-updater/state.json`。Backend 或浏览器在切换期间断线不会终止宿主机操作,恢复后可继续读取日志。
## 自动回退
停服后的迁移、启动或健康验证失败会触发自动回退:
1. 停止目标 web/backend;
2. 恢复更新前保存的 Compose 文件;
3. 恢复更新前保存的 `.env`,确保 backend/web 镜像仍绑定到原 digest;
4. 再次校验备份 ZIP 和 SHA-256;
5. 使用 `pg_restore --clean --if-exists` 恢复 PostgreSQL;
6. 启动旧服务并重新进行稳定窗口验证。
回退任一步失败时状态变为 `manual_intervention`,不伪造成功。管理后台仅在存在旧版本和已校验备份时开放人工回退按钮。
## 安装与升级约束
GHCR 镜像部署必须把 `CANVAS_IMAGE_TAG` 固定到具体 Release,并把 `CANVAS_BACKEND_IMAGE`、`CANVAS_WEB_IMAGE` 固定到对应 GHCR digest,不可使用 `latest` 或仅使用可变 tag。首次安装时显式指定 Release:
```bash
curl -fsSL https://raw.githubusercontent.com/ddcat-ai/open-ai-canvas/main/scripts/install-server-image.sh \
| sudo env CANVAS_IMAGE_TAG=v1.5.7.1 bash
```
已有部署只安装更新器时,先确认 `.env` 已包含两个 `@sha256:...` 镜像引用,再执行:
```bash
cd /opt/open-ai-canvas
curl -fsSL https://raw.githubusercontent.com/ddcat-ai/open-ai-canvas/main/scripts/install-host-updater.sh | sudo bash
```
脚本会下载与当前 Release 匹配的 Linux amd64/arm64 二进制和 `SHA256SUMS`,生成随机 `CANVAS_UPDATER_TOKEN`,创建 systemd 服务、Socket 目录、状态目录和 `backups/`。Token 只保存在服务器 `.env` 与 root-only 更新器环境文件中。
## 镜像发布与质量门禁
`main` 推送、`v*` 标签和手动发布统一由 `.github/workflows/publish-images.yml` 编排。发布先调用可复用的 `quality.yml`;PR 仍直接运行质量检查。Go 测试、前端格式、类型、Lint、单测和 Chrome E2E 任一失败,都不能进入镜像构建和发布阶段。若仓库规则配置了必需检查,切换后应核对实际 check 名称,避免仍等待旧的独立 push 工作流。
构建和发布分为以下阶段:
1. 校验 `VERSION`;版本标签必须与文件一致,且存在对应 `CHANGELOG.md` 标题。构建时间取提交时间,同一 SHA 不因重跑而改变。
2. 后端分别在 `ubuntu-24.04`(AMD64)和 `ubuntu-24.04-arm`(ARM64)原生编译,保留 CGO 与三个服务/迁移二进制。支付插件在每个平台的镜像阶段重新打包并执行 smoke;PR 则独立执行双架构 smoke,不依赖发布。
3. 前端 Bun 构建阶段固定到 `BUILDPLATFORM`,静态资源只生成一次,再放入 AMD64/ARM64 nginx 镜像。Bun 与 `web/package.json`、质量检查保持 `1.3.9` 一致。
4. 先推送 `sha-<完整提交>-amd64/arm64` 后端镜像及 `sha-<完整提交>-multi` 前端镜像,以摘要 artifact 传递结果。两种后端架构和前端全部成功后,才从摘要合并发布 manifest,不用可变标签作为合并源。
5. 同一 SHA 的 main/tag 发布串行运行;后到的一轮仍经过质量门禁,然后复用已有 SHA 镜像,不重复编译。只有明确的镜像不存在可以转入构建,鉴权、限流、网络和异常摘要必须报错。
6. 发布保留完整 SHA 和短 SHA 标签;只有版本 tag 推送写入具体版本标签。`main` 只有在仍是远端最新提交时才更新 `latest`,旧提交的慢任务不能覆盖新版本。正式部署由安装器和更新器解析并落盘 digest,不依赖 `latest`。
Go 检查显式使用 `backend/go.sum` 作为缓存依赖键,并上传 `go-test-timings`(JSONL),可按 `Test` / `Elapsed` 定位慢测试。Docker 的后端模块下载保留在普通镜像层,编译步骤可以直接读取;支付插件只按实际 import 下载依赖,不重复预取完整后端模块图。版本参数下移到编译入口。GHA 构建缓存按镜像和架构隔离,避免并行任务共用同一 scope。`go-build` cache mount 只用于同一个 builder 内的复用,当前没有额外的跨 Runner mount 导出方案;不能把它当作持久编译缓存。冷缓存首轮和缓存上传仍可能较慢,需要比较连续两轮的实际耗时。
这套发布流程依赖仓库可使用 GitHub 原生 ARM64 Runner、GHCR 写权限以及构建/下载 artifact 能力。首次上线应核对实际 Runner 排队情况、双架构 manifest、main/tag 同 SHA 复用和质量失败阻断;本地测试不能代替这些云端验收。工作流变更不迁移业务数据库,也不修改服务器 Compose 或数据卷。需要回退 CI 时只回退工作流和 Dockerfile 改动;已发布镜像不会自动撤回,线上版本回退仍按本文的备份与迁移约束执行。
## 运维检查
```bash
sudo systemctl status open-ai-canvas-updater
sudo journalctl -u open-ai-canvas-updater -n 200 --no-pager
sudo ls -lh /opt/open-ai-canvas/backups
sudo sha256sum /opt/open-ai-canvas/backups/*.zip
```
备份文件包含业务数据,应限制为 root 访问并纳入异机备份策略。数据卷本身不是备份。