Files
my_bookmate/deploy/README.md
T
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

6.4 KiB
Raw Blame History

BookMate 云服务器部署手册(Docker + nginx-proxy-manager)

服务器已装 Docker 与 nginx-proxy-manager(NPM)。BookMate 由 backend(FastAPI:8000)与 frontend(Next.js:3000)两个容器组成,挂到 NPM 所在网络,由 NPM 用域名反代 + TLS。 不暴露任何宿主端口,不会和你服务器上的其它应用冲突。

0. 准备

把仓库放到服务器(二选一):

# 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 锁),再拷贝。

# 在服务器上(目录结构照做)
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

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. 构建并启动

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. 日常运维

# 更新到最新代码并重建
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 一律不动,可反复执行:

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 表,不会删除它们; 若丢失先检查是否误清了数据卷或迁移了旧库。