From 47ca72a62a931180d2a2cee9a7ed4093c19685b5 Mon Sep 17 00:00:00 2001 From: Shuming Liu Date: Mon, 17 Aug 2026 09:26:42 +0800 Subject: [PATCH] fixed docs --- sentence_api/DEPLOYMENT.md | 4 + sentence_api/UPDATE.md | 188 +++++++++++++++++++++++++++++++++++++ 2 files changed, 192 insertions(+) create mode 100644 sentence_api/UPDATE.md diff --git a/sentence_api/DEPLOYMENT.md b/sentence_api/DEPLOYMENT.md index c6e1a3e..d17e292 100644 --- a/sentence_api/DEPLOYMENT.md +++ b/sentence_api/DEPLOYMENT.md @@ -372,3 +372,7 @@ sqlite3 sentence_api/data/oral_trainer.sqlite3 \ ``` 升级前先备份数据库和 `data/v/`。API 重启期间被中断的视频会保留 `processing` 状态,可从后台执行“重新处理”。 + +## 9. 更新与回滚 + +日常代码更新、镜像升级与回滚流程见 [`UPDATE.md`](UPDATE.md)。 diff --git a/sentence_api/UPDATE.md b/sentence_api/UPDATE.md new file mode 100644 index 0000000..3a10e1b --- /dev/null +++ b/sentence_api/UPDATE.md @@ -0,0 +1,188 @@ +# 更新与回滚操作文档 + +本文档说明生产服务器上如何更新代码、更新镜像、以及出现问题时如何回滚。 +适用服务器:`lsmserver`(Ubuntu,Docker Compose + systemd 部署)。 + +## 0. 环境速览 + +| 服务 | 源码/配置位置 | 运行方式 | 容器名 | 数据位置 | +| --- | --- | --- | --- | --- | +| API | `/home/ubuntu/mediaplayer`(git 仓库) | `docker compose up -d --build` | `sentence_api-oral-trainer-api-1` | `/home/ubuntu/mediaplayer/sentence_api/data` | +| Whisper | 部署副本 `/opt/whisper`(来自仓库 `whisper/`) | systemd:`whisper-transcribe.service` | `whisper-transcribe` | 模型缓存在 Docker 卷 `hf-hub-cache` | +| Nginx | `/etc/nginx/sites-available/oral-trainer` | systemd:`nginx` | — | — | + +关键事实: + +- API 的代码是**构建进镜像**的(Dockerfile 里 `COPY sentence_api /app/sentence_api`), + 只 `git pull` 不会让运行中的容器生效,必须重新构建并重建容器。 +- 只有 `./data` 被挂载进容器,重建容器不影响视频和数据库。 +- Whisper 的 `/opt/whisper` 是仓库 `whisper/` 目录的副本,`git pull` 不会自动同步到 + `/opt/whisper`,需要手动复制。 +- Whisper 的 systemd 模板 `ExecStop` 是 `docker compose down`(若未改过), + `systemctl stop whisper-transcribe` 会删除容器;日常请用 `systemctl restart`。 + +## 1. 更新前准备 + +### 1.1 确认当前状态正常 + +```bash +docker ps # 两个容器都在运行 +curl http://127.0.0.1:8000/healthz # API 正常 +curl http://127.0.0.1:9000/v1/models # Whisper 正常 +``` + +### 1.2 记录当前版本,便于回滚 + +```bash +cd /home/ubuntu/mediaplayer +git rev-parse HEAD # 记录当前 commit +git status # 确认没有未提交的本地改动 +docker images | grep sentence_api # 记录当前镜像 +``` + +### 1.3 备份数据(强烈建议每次更新前执行) + +```bash +cd /home/ubuntu/mediaplayer/sentence_api + +# 停 API 保证 SQLite 备份一致 +docker compose stop oral-trainer-api + +mkdir -p /home/ubuntu/backups +sudo tar -czf "/home/ubuntu/backups/oral-trainer-$(date +%F-%H%M).tar.gz" data + +# 恢复启动 +docker compose up -d +``` + +备份文件包含全部视频、录音和数据库,放在 `/home/ubuntu/backups/`。 + +## 2. 更新 API(最常见) + +```bash +cd /home/ubuntu/mediaplayer +git pull # 拉取最新代码 + +cd sentence_api +docker compose up -d --build # 重新构建镜像并重建容器 +``` + +验证: + +```bash +docker compose ps # 状态应为 healthy +docker compose logs -f oral-trainer-api # 看启动日志 +curl http://127.0.0.1:8000/healthz +``` + +确认新代码已生效: + +```bash +docker images | grep sentence_api # 看镜像创建时间是否为刚才 +``` + +### 2.1 只改了 `.env`(无需重新构建) + +```bash +cd /home/ubuntu/mediaplayer/sentence_api +docker compose up -d # 检测到配置变化会自动重建容器 +``` + +### 2.2 只改了 Nginx 配置 + +```bash +sudo cp sentence_api/nginx.conf.example /etc/nginx/sites-available/oral-trainer +sudo nginx -t +sudo systemctl reload nginx +curl -H 'Host: video_service.d1kt.cn' http://127.0.0.1/healthz +``` + +## 3. 更新 Whisper(不常需要) + +Whisper 的代码不常变;以下情况才需要更新: + +- 改了 `/opt/whisper` 里的配置或 compose 文件; +- 想升级镜像(`ghcr.io/speaches-ai/speaches:latest-cuda` 是 latest 标签, + 不会自动拉新版本)。 + +```bash +# 1. 拉代码并同步到 /opt/whisper(保留服务器上的 .env,不覆盖) +cd /home/ubuntu/mediaplayer +git pull +rsync -a --exclude .env whisper/ /opt/whisper/ + +# 2. 如果 compose 或 systemd 单元文件有改动,先重载 +sudo systemctl daemon-reload + +# 3. 如果需要升级镜像 +cd /opt/whisper +docker compose pull + +# 4. 重启服务(会自动重建容器) +sudo systemctl restart whisper-transcribe +``` + +验证: + +```bash +systemctl status whisper-transcribe +curl http://127.0.0.1:9000/v1/models +``` + +注意:模型缓存在 Docker 卷 `hf-hub-cache` 里,重启不会重新下载模型。 + +## 4. 回滚 + +### 4.1 回滚 API 代码 + +```bash +cd /home/ubuntu/mediaplayer +git log --oneline -5 # 找到要回退到的 commit + +# 方式一:回退到指定版本(会生成反向提交,保留 git 历史) +git revert <有问题的commit> + +# 方式二:直接切回旧 commit(分离头指针,之后记得切回分支) +git checkout <上一版commit> + +# 重新构建并重建容器 +cd sentence_api +docker compose up -d --build +``` + +验证回滚是否生效:`curl http://127.0.0.1:8000/healthz`,并观察日志。 + +### 4.2 回滚数据 + +```bash +cd /home/ubuntu/mediaplayer/sentence_api +docker compose stop oral-trainer-api + +# 用更新前备份恢复(会覆盖当前数据,请确认) +sudo tar -xzf /home/ubuntu/backups/oral-trainer-<备份时间>.tar.gz -C . + +docker compose up -d +``` + +### 4.3 回滚 Whisper + +```bash +# 从仓库历史中取出旧版 whisper/ 文件,重新同步 +cd /home/ubuntu/mediaplayer +git checkout <上一版commit> -- whisper/ + +rsync -a --exclude .env whisper/ /opt/whisper/ +sudo systemctl restart whisper-transcribe +``` + +## 5. 常见问题排查 + +| 现象 | 原因 | 处理 | +| --- | --- | --- | +| 更新后接口行为没变 | 忘了 `--build`,容器还在跑旧镜像 | 执行 `docker compose up -d --build` | +| 构建时 pip 安装超时 | 服务器访问 PyPI 受限 | 给 Dockerfile 的 pip install 加 `-i https://pypi.tuna.tsinghua.edu.cn/simple` 后重新构建 | +| 构建时拉基础镜像超时 | Docker Hub 网络问题 | 检查 `/etc/docker/daemon.json` 的 `registry-mirrors`(已配置 DaoCloud) | +| `healthz` 里 `moss_configured: false` | `.env` 里 `MOSS_TRANSCRIBE_URL` 为空或改了未重建 | 改 `.env` 后执行 `docker compose up -d` | +| Whisper 9000 端口连不上 | 服务未运行或容器被删 | `systemctl status whisper-transcribe`;容器被删时用 `systemctl start` 重建 | +| API 重启后视频卡在 `processing` | 重启中断了处理流程 | 后台点“重新处理”即可 | +| `git pull` 失败 | 本地有未提交改动或认证问题 | `git status` 检查;`git stash` 暂存改动;确认 `git remote -v` 和凭据 |