Files
gavindiazandClaude Code 0ca4fcce65 docs: 更新/重写项目文档(README / 部署手册 / 前端说明)
- README.md:补充原生分页 / 连续选取 / 摘录高亮说明;阅读位置改为
  服务端跨设备同步(不再是「当前浏览器保存」);补「第二大脑」助手
  与模型管理入口;验证命令改为 venv 内 python
- deploy/README.md:修正 git clone 后的实际目录结构;新增第 8 节
  「历史遗留数据清理」(clean_orphans 脚本 + 启动迁移自动清理),
  并在常见问题里补跨设备位置 / 删书不彻底 / 脚本 ModuleNotFound 等
- frontend/README.md:整体重写,去掉 create-next-app 模板残留
  (Vercel / Geist),改为项目真实结构 / 模块说明 / 本地开发 / 构建
- 删除 backend/AGENTS.md:Next.js 自动生成的残留块,backend 目录为
  FastAPI 项目、无 node_modules/next,删除避免误导(frontend 那份保留)

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-27 22:30:22 +08:00

151 lines
6.4 KiB
Markdown
Raw Permalink 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.
# BookMate 云服务器部署手册(Docker + nginx-proxy-manager)
> 服务器已装 Docker 与 nginx-proxy-manager(NPM)。BookMate 由 `backend`(FastAPI:8000)与
> `frontend`(Next.js:3000)两个容器组成,挂到 NPM 所在网络,由 NPM 用域名反代 + TLS。
> **不暴露任何宿主端口**,不会和你服务器上的其它应用冲突。
## 0. 准备
把仓库放到服务器(二选一):
```bash
# A. git 克隆(推荐,后续更新方便)
# 注意:git clone 会在目标目录下再建一层仓库名子目录,
# 下文统一用「仓库根目录」指代实际目录(/opt/bookmate/my_bookmate)
git clone https://code.aifunny.ltd/gavindiaz/my_bookmate.git /opt/bookmate
cd /opt/bookmate/my_bookmate
# B. 或从本机拷贝(不含 .git 也行)
# scp -r ./bookmate user@server:/opt/bookmate/
```
## 1. 迁移现有数据(保留书库 / 对话 / 向量)
> 只迁移 `backend/data`(含 `bookmate.db`)和 `backend/uploads`(EPUB 原文件)。
> 先确认本机后端已停止(避免 db 锁),再拷贝。
```bash
# 在服务器上(目录结构照做)
mkdir -p /opt/bookmate/deploy/data /opt/bookmate/deploy/uploads
# 本机执行(把路径换成你的)
scp backend/data/bookmate.db user@server:/opt/bookmate/deploy/data/
scp -r backend/uploads/. user@server:/opt/bookmate/deploy/uploads/
```
不迁移也能跑:服务器从空书库开始,之后在网页里重新导入即可。
## 2. 配置 .env
```bash
cd /opt/bookmate
cp .env.example .env
# 编辑 .env,必改项:
# NEXT_PUBLIC_API_BASE=https://你的域名/api
# NPM_NETWORK= ← 服务器上 `docker network ls` 查到 NPM 所在网络名
# SITE_PASSWORD= ← 站点访问密码(必须设,否则任何人可访问)
# DEEPSEEK_API_KEY / OPENROUTER_API_KEY / EMBEDDING_API_KEY / RERANK_API_KEY 等
```
## 3. 构建并启动
```bash
cd /opt/bookmate
docker compose up -d --build
docker compose ps # 两个容器都应为 Up
# 无 NPM 时直连验证:
curl http://localhost:8000/api/health # {"status":"ok"}
curl http://localhost:3000 # 前端 HTML
```
## 4. NPM 反向代理 + TLS
NPM 网页(通常 http://服务器IP:81)→ Hosts → Add Proxy Host:
- **Domain Names**:`bookmate.example.com`(改成你的)
- **Forward Hostname / Port**:
- 根路径:`frontend` / `3000`
- **Custom Locations**(添加两段,最长前缀优先):
| Location | Forward Hostname | Port |
|---|---:|---:|
| `/api` | `backend` | `8000` |
| `/` | `frontend` | `3000` |
- **SSL**:Request a new SSL Certificate → Let's Encrypt → 勾选 Force SSL。
SSE 流式与文件上传都是普通 HTTP,NPM 无需 websocket 特殊配置。
## 5. DNS
把 `bookmate.example.com` 的 **A 记录**指向服务器公网 IP,等解析生效即可访问
`https://bookmate.example.com`。
## 6. 验证
1. 打开 `https://bookmate.example.com` → 出现登录页 → 输入 SITE_PASSWORD。
2. 书库应显示迁移过来的书;打开一本书能看到迁移的对话。
3. 上传一本新 EPUB → 对话提问 → 确认流式回答与引用正常。
4. 发一条「第二大脑 / AI 助手」消息 → 确认工具(bm_*)能调用。
## 7. 日常运维
```bash
# 更新到最新代码并重建
cd /opt/bookmate/my_bookmate
git pull
docker compose up -d --build
# 看日志
docker compose logs -f backend
docker compose logs -f frontend
# 备份(只备份数据即可,镜像可重建)
tar czf bookmate-data-backup.tgz deploy/data deploy/uploads
```
如果 `git pull` 后容器里没看到新代码,说明改动可能只进过数据库迁移/脚本目录——
`docker compose up -d --build` 会重新构建镜像,把新文件烧进去。
## 8. 历史遗留数据清理(孤儿 DB 行 / uploads 文件)
早期版本删书时因 `file_path` 存的是 Windows 相对路径 + SQLite 外键未强制开启,
可能残留无主的数据库行(segments / chapters / reading_notes / reading_progress /
conversations / messages)和 `deploy/uploads` 下无书籍记录的 `.epub` 文件。
清理脚本只删「无主」数据,现存的书籍、笔记、对话、模型、MCP 一律不动,可反复执行:
```bash
cd /opt/bookmate/my_bookmate
docker compose up -d --build # 先把脚本打镜像(首次必须)
docker compose exec backend python -m app.scripts.clean_orphans
```
输出会列出各表删除的行数与被删的 epub 文件名;无残留时全部为 0。
后端启动迁移每次也会自动清孤儿 DB 行(缺新表时自动跳过),因此 `docker compose restart backend`
同样能清理 DB 残留;uploads 文件残留仍需上面的脚本。
## 大陆网络
Dockerfile 已把国内源烘焙成默认值(可在构建时用 `--build-arg` 覆盖为官方源):
- backend 的 pip:默认 `https://pypi.tuna.tsinghua.edu.cn/simple`
- frontend 的 npm:默认 `https://registry.npmmirror.com`
基础镜像(`python:3.12-slim` / `node:22-alpine`)来自 Docker Hub,大陆直连可能很慢/失败:
- 临时用代理拉一次后即缓存(`docker pull python:3.12-slim && docker pull node:22-alpine`);
- 或给 Docker 配置 registry 镜像加速(如阿里云容器镜像服务),长期更稳。
## 常见问题
- **NPM 连不上容器**:`NPM_NETWORK` 没填对。`docker network ls` 确认 NPM 所在网络名,
填到 `.env` 后 `docker compose down && docker compose up -d` 重建网络连接。
- **页面能开但接口 404**:`/api` 的 Custom Location 没加,或 `NEXT_PUBLIC_API_BASE` 端口/域名
与 NPM 配置不一致(它内联在构建产物里,改了要重新 build)。
- **向量没生效**:确认 `EMBEDDING_API_KEY` / `RERANK_API_KEY` 已填;上传新书后后台会自动生成向量。
- **换设备阅读位置不续上**:位置存在服务端(`reading_notes` 之外的 `reading_progress` 表),
同一本书两端应一致;若不一致,确认前端已更新到含 `GET/PUT /books/{id}/progress` 的版本并重新 build。
- **删书后文件还在 / DB 不缩水**:跑一遍上面的清理脚本(第 8 节);SQLite 的 DELETE 不缩文件,
脚本结尾的 VACUUM 会真正压缩 db。
- **`python -m app.scripts.clean_orphans` 报 ModuleNotFoundError**:镜像太旧,
重新 `docker compose build backend && docker compose up -d`。
- **模型 / MCP 配置消失**:清理脚本不涉及 `ai_models` / `mcp_servers` 表,不会删除它们;
若丢失先检查是否误清了数据卷或迁移了旧库。