BookOrbit 自托管阅读平台完整部署教程
本文档基于一次真实的部署过程整理,涵盖了从零开始部署 BookOrbit 的全流程,以及过程中遇到的各种问题及解决方案。
一、BookOrbit 是什么?
BookOrbit 是一个开源的自托管数字图书馆和阅读平台,你可以把它理解为「私有云书架」—— 所有数据都保存在你自己的服务器上,不需要依赖任何第三方服务。
它能做什么?
📚 统一管理多种阅读内容
支持 EPUB、KEPUB、MOBI、AZW3、PDF 等电子书格式,以及 CBZ/CBR 漫画和 M4B/MP3/FLAC 有声书。所有内容在一个平台上管理,不需要在多个应用之间切换。
🔍 自动补全书籍信息
从 Google Books、Amazon、Goodreads、Open Library 等 9 个来源自动抓取封面、作者、简介等元数据,并支持字段级锁定,你可以决定哪些信息被更新、哪些保留。
📱 多设备阅读同步
支持与 Kobo 阅读器深度集成,书籍自动推送,阅读进度双向同步。也支持 OPDS 协议,可连接 KOReader、Thorium、Moon Plus Reader 等第三方阅读应用。对于 Kindle 用户,支持 Send-to-Kindle 邮件投递。
📊 阅读统计与分析
提供每日阅读时间统计、热力图、连续阅读记录、阅读目标追踪等功能,无需依赖 Goodreads 等第三方服务。
👨👩👧👦 家庭共享
支持多用户独立账户,每个人的阅读进度和数据相互隔离,可与家人共享书库。
为什么选它而不是 Calibre 或 Kavita?
- 相比 Calibre:BookOrbit 提供更现代化的 Web 界面和 Docker 部署体验,同时原生支持有声书和漫画管理,不像 Calibre 需要各种插件和配置。
- 相比 Kavita:部分用户选择 BookOrbit 是因为它没有将高级功能置于付费墙之后,功能完全开源。
- 相比 Audiobookshelf:BookOrbit 胜在支持 Kobo/KOReader 同步,且多媒体库的展示和管理方式更统一。
二、环境要求
- 操作系统:Linux (Ubuntu/Debian 推荐)
- 配置要求:至少 2GB 内存,建议 4GB+(尤其是需要同时运行其他 Docker 服务时)
- 软件依赖:Docker & Docker Compose
- 网络:能够访问 GitHub Container Registry (ghcr.io),国内可能较慢
三、完整部署步骤
以下所有命令均在服务器终端执行。
第一步:创建项目目录
mkdir -p /wwwroot/bookorbit
cd /wwwroot/bookorbit
第二步:创建 docker-compose.yml
cat > docker-compose.yml << 'EOF'
services:
bookorbit:
image: ghcr.io/bookorbit/bookorbit:latest
container_name: bookorbit-app
ports:
- "8090:3000"
volumes:
- ./data:/app/data
- ./books:/books
- ./auto_ingest:/app/data/book-dock
environment:
- DB_HOST=postgres
- DB_PORT=5432
- PGUSER=bookorbit
- PGPASSWORD=bookorbit@123
- PGDATABASE=bookorbit
- POSTGRES_USER=bookorbit
- POSTGRES_PASSWORD=bookorbit@123
- POSTGRES_DB=bookorbit
- JWT_SECRET=your_jwt_secret_here_min_32_chars
- SETUP_BOOTSTRAP_TOKEN=your_setup_token_here
- HOST=0.0.0.0
- PORT=3000
- NODE_ENV=production
depends_on:
- postgres
restart: unless-stopped
networks:
- bookorbit-net
postgres:
image: pgvector/pgvector:pg15
container_name: bookorbit-db
environment:
- POSTGRES_USER=bookorbit
- POSTGRES_PASSWORD=bookorbit@123
- POSTGRES_DB=bookorbit
volumes:
- ./pgdata:/var/lib/postgresql/data
restart: unless-stopped
networks:
- bookorbit-net
networks:
bookorbit-net:
driver: bridge
EOF
第三步:生成安全密钥
BookOrbit 在生产环境强制要求两个安全密钥。执行以下命令生成并自动替换到配置文件中:
JWT_SECRET=$(openssl rand -base64 32 | tr -d '\n')
SETUP_TOKEN=$(openssl rand -base64 16 | tr -d '\n')
echo "JWT_SECRET=$JWT_SECRET"
echo "SETUP_BOOTSTRAP_TOKEN=$SETUP_TOKEN"
sed -i "s|your_jwt_secret_here_min_32_chars|$JWT_SECRET|g" docker-compose.yml
sed -i "s|your_setup_token_here|$SETUP_TOKEN|g" docker-compose.yml
第四步:设置目录权限
这是最容易忽略但最关键的一步。Docker 容器内运行的用户 UID 是 1000,如果宿主机目录权限不对,上传文件时会报 Internal Server Error。
mkdir -p data books auto_ingest pgdata
sudo chown -R 1000:1000 data books auto_ingest pgdata
sudo chmod -R 755 data books auto_ingest pgdata
第五步:启动服务
docker-compose up -d
docker-compose ps
docker-compose logs -f bookorbit
第六步:验证部署
curl -I http://127.0.0.1:8090
看到 HTTP/1.1 200 OK 表示部署成功。
四、常见问题及解决方案
Q1: 镜像拉取缓慢
国内访问 GitHub Container Registry 速度较慢,可配置 Docker 镜像加速器,或耐心等待。
Q2: 端口被占用
错误信息:Bind for 0.0.0.0:8090 failed: port is already allocated
查看端口占用:
sudo lsof -i :8090
sudo netstat -tlnp | grep 8090
解决方案:修改 docker-compose.yml 中的端口映射为其他端口,如 "8099:3000"
Q3: 数据库连接失败
错误信息:getaddrinfo ENOTFOUND postgres
原因:容器不在同一个 Docker 网络中,或网络未正确创建。
解决方案:
docker-compose down
docker-compose up -d
docker network inspect bookorbit_bookorbit-net
Q4: 缺少 JWT_SECRET 或 SETUP_BOOTSTRAP_TOKEN
错误信息:
JWT_SECRET: Invalid input: expected string, received undefined
SETUP_BOOTSTRAP_TOKEN is required in production
解决方案:按照部署步骤第三步生成并配置这两个环境变量。
Q5: 容器内端口映射错误
现象:容器状态显示 Running,但 curl 返回 Connection reset by peer。
原因:BookOrbit 容器内实际监听的是 3000 端口,如果映射为 8090:8080 会导致连接被重置。
解决方案:修改端口映射为 "8090:3000"。
Q6: extension "vector" is not available
错误信息:extension "vector" is not available
原因:使用了普通 postgres 镜像,缺少 BookOrbit 所需的 vector 扩展。
解决方案:使用 pgvector/pgvector:pg15 镜像替代 postgres:15-alpine。
Q7: 前端上传文件返回 Internal Server Error
原因:目录权限不足,容器用户无法写入挂载目录。
解决方案:
sudo chown -R 1000:1000 /wwwroot/bookorbit/data
sudo chown -R 1000:1000 /wwwroot/bookorbit/books
sudo chmod -R 755 /wwwroot/bookorbit/data
sudo chmod -R 755 /wwwroot/bookorbit/books
Q8: 服务器崩溃/卡死,所有服务无法访问
原因及解决方案:
- 通过宝塔面板文件管理器上传电子书会触发文件监控事件,可能导致解析死锁 —— 禁止使用宝塔面板传书!
- 大量书籍同时扫描时 CPU/内存耗尽 —— 分批导入,每次 10-20 本
- 容器未限制资源使用 —— 限制容器 CPU 和内存
紧急恢复命令:
docker kill bookorbit-app
systemctl stop docker
限制资源使用:
docker update --cpus=0.5 --memory=512M bookorbit-app
docker update --cpus=0.5 --memory=512M bookorbit-db
Q9: Setup token 页面为空,无法填写
原因:前端缓存了旧页面,环境变量未正确注入。
解决方案:
- 确认 docker-compose.yml 中 SETUP_BOOTSTRAP_TOKEN 已配置
- 浏览器按 Ctrl+F5 强制刷新,或使用无痕模式访问
- 如果页面仍要求输入,直接粘贴配置文件中的 Token 值即可
Q10: 外部无法访问
排查步骤:
ufw status
ufw allow 8090/tcp
同时检查云服务商安全组,确保 8090 端口已放行。
五、错误原因总结
本次部署过程中遇到的所有错误及根本原因:
- 镜像拉取缓慢 —— 国内访问 GitHub Container Registry 速度慢
- 端口 8090 被占用 —— 其他 Docker 容器占用了该端口
- getaddrinfo ENOTFOUND postgres —— 容器未在同一 Docker 网络中
- JWT_SECRET 未定义 —— 未设置 JWT_SECRET 环境变量
- SETUP_BOOTSTRAP_TOKEN 未定义 —— 未设置 SETUP_BOOTSTRAP_TOKEN 环境变量
- extension "vector" is not available —— 使用了普通 PostgreSQL 镜像
- Connection reset by peer —— 端口映射错误,容器内监听 3000 但映射到 8080
- Internal Server Error —— 目录权限不足,容器用户无法写入
- 服务器完全崩溃 —— 宝塔面板上传电子书触发文件监控死锁
- Setup token 页面为空 —— 前端缓存未刷新
关键教训:
- 生产环境必须设置 JWT_SECRET 和 SETUP_BOOTSTRAP_TOKEN
- 端口映射必须与容器内监听端口一致(3000)
- 必须使用 pgvector/pgvector:pg15 作为数据库镜像
- 目录权限必须在启动前设置(UID 1000)
- 绝对禁止用宝塔面板文件管理器上传电子书
- 容器必须限制资源使用
- 配置变更后需强制刷新浏览器
六、最终配置文件
以下是经过完整测试的最终 docker-compose.yml:
services:
bookorbit:
image: ghcr.io/bookorbit/bookorbit:latest
container_name: bookorbit-app
ports:
- "8090:3000"
volumes:
- ./data:/app/data
- ./books:/books
- ./auto_ingest:/app/data/book-dock
environment:
- DB_HOST=postgres
- DB_PORT=5432
- PGUSER=bookorbit
- PGPASSWORD=bookorbit@123
- PGDATABASE=bookorbit
- POSTGRES_USER=bookorbit
- POSTGRES_PASSWORD=bookorbit@123
- POSTGRES_DB=bookorbit
- JWT_SECRET=k5z0BcJsS4g3H+ih9ghoOjJW1ij+woT6pV4fXaBarvI=
- SETUP_BOOTSTRAP_TOKEN=GYjK8vPqXXMYZ26H3AzdHw==
- HOST=0.0.0.0
- PORT=3000
- NODE_ENV=production
depends_on:
- postgres
restart: unless-stopped
networks:
- bookorbit-net
postgres:
image: pgvector/pgvector:pg15
container_name: bookorbit-db
environment:
- POSTGRES_USER=bookorbit
- POSTGRES_PASSWORD=bookorbit@123
- POSTGRES_DB=bookorbit
volumes:
- ./pgdata:/var/lib/postgresql/data
restart: unless-stopped
networks:
- bookorbit-net
networks:
bookorbit-net:
driver: bridge
七、使用指南
添加书籍的三种方式
方式一:Web 界面上传(推荐)
登录 BookOrbit → 进入书库 → 点击上传按钮 → 选择文件
方式二:自动摄入目录(Book Dock)
将书籍放入 /wwwroot/bookorbit/auto_ingest/ 目录,系统会自动识别并导入
cp /path/to/book.epub /wwwroot/bookorbit/auto_ingest/
方式三:SSH/SCP 上传到 books 目录
scp -P 22 book.epub root@your_ip:/wwwroot/bookorbit/books/
然后在 Web 界面手动触发扫描
常用 Docker 命令
docker-compose up -d 启动
docker-compose down 停止
docker-compose logs -f 查看日志
docker-compose restart 重启
docker-compose pull && docker-compose up -d 更新镜像并重启
目录结构说明
/wwwroot/bookorbit/
├── docker-compose.yml
├── data/ 应用数据(元数据、封面、配置等)
├── books/ 主书库目录(存放已整理的电子书)
├── auto_ingest/ 自动摄入目录(Book Dock,用于导入新书)
└── pgdata/ PostgreSQL 数据库文件
首次使用流程
- 浏览器访问 http://你的服务器IP:8090
- 创建管理员账户
- 在设置中创建书库(Library),扫描目录填 /books
- 开始上传或导入书籍
八、重要教训
绝对禁止的操作
- 使用宝塔面板文件管理器上传电子书到 BookOrbit 目录 → 会触发文件监控导致服务器完全崩溃
- 一次性上传大量书籍 → 资源耗尽,建议每次 10-20 本
- 不设置资源限制 → 容器可能耗尽宿主机资源
- 忽略目录权限 → 导致上传失败
最佳实践
- 通过 Web 界面上传是最安全的方式
- 使用 auto_ingest 目录实现自动处理,省心省力
- 分批导入书籍,避免负载过高
- 开启容器的 CPU 和内存限制
- 定期备份 data、books、pgdata 三个目录
关键配置点速查
端口映射:宿主机:容器,容器内实际监听端口是 3000
数据库镜像:必须使用 pgvector/pgvector:pg15,包含 vector 扩展
安全密钥:JWT_SECRET 和 SETUP_BOOTSTRAP_TOKEN 必须设置
目录权限:容器用户 UID 是 1000,需 chown -R 1000:1000
资源限制:建议 --cpus=0.5 --memory=512M
九、结语
遇到问题时,查看日志是解决问题的第一步:
docker-compose logs -f bookorbit
BookOrbit 是一个功能强大的自托管阅读平台,虽然部署过程中可能会遇到各种问题,但只要按照本文档的步骤逐一排查,最终一定能顺利运行。祝你的私人书库顺利搭建!