2026-10-25 15:35:20 +08:00
|
|
|
|
# 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 克隆(推荐,后续更新方便)
|
2026-10-27 22:30:22 +08:00
|
|
|
|
# 注意:git clone 会在目标目录下再建一层仓库名子目录,
|
|
|
|
|
|
# 下文统一用「仓库根目录」指代实际目录(/opt/bookmate/my_bookmate)
|
2026-10-25 15:35:20 +08:00
|
|
|
|
git clone https://code.aifunny.ltd/gavindiaz/my_bookmate.git /opt/bookmate
|
2026-10-27 22:30:22 +08:00
|
|
|
|
cd /opt/bookmate/my_bookmate
|
2026-10-25 15:35:20 +08:00
|
|
|
|
|
|
|
|
|
|
# B. 或从本机拷贝(不含 .git 也行)
|
2026-10-27 22:30:22 +08:00
|
|
|
|
# scp -r ./bookmate user@server:/opt/bookmate/
|
2026-10-25 15:35:20 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## 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
|
|
|
|
|
|
# 更新到最新代码并重建
|
2026-10-27 22:30:22 +08:00
|
|
|
|
cd /opt/bookmate/my_bookmate
|
2026-10-25 15:35:20 +08:00
|
|
|
|
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
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2026-10-27 22:30:22 +08:00
|
|
|
|
如果 `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 文件残留仍需上面的脚本。
|
|
|
|
|
|
|
2026-10-25 15:35:20 +08:00
|
|
|
|
## 大陆网络
|
|
|
|
|
|
|
|
|
|
|
|
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` 已填;上传新书后后台会自动生成向量。
|
2026-10-27 22:30:22 +08:00
|
|
|
|
- **换设备阅读位置不续上**:位置存在服务端(`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` 表,不会删除它们;
|
|
|
|
|
|
若丢失先检查是否误清了数据卷或迁移了旧库。
|