Readest 官方自建同步服务器部署指南
适用环境:Ubuntu + Nginx + Docker Compose
目标设备:Windows、Android
主要格式:EPUB、PDF、TXT
核对日期:2026-11-09(Asia/Shanghai)
正式部署范围:仅 Readest 官方仓库、官方容器镜像和官方自建网页端
1. 结论与方案边界
推荐架构:
| |
官方 Docker Compose 栈包含 Readest Web、Supabase PostgreSQL、Kong、GoTrue、PostgREST 和 MinIO。书架、阅读进度、书签、高亮、笔记等结构化数据进入 PostgreSQL;电子书文件进入 MinIO。
本方案的正式客户端是官方自建网页端:
- Windows:Edge、Chrome 等 Chromium 浏览器访问;浏览器提供“安装应用”时可安装为网页应用。
- Android:Chrome 等浏览器访问;浏览器提供“安装应用”或“添加到主屏幕”时可安装。
- 官方文档确认 Web 版首次访问后可离线工作,但是否显示完整 PWA 安装入口取决于浏览器、系统及站点条件。没有安装入口时,直接使用网页或添加桌面快捷方式即可。
本方案不把官方 Windows EXE、Android APK 连接自建后端列为正式步骤。截至核对日期,官方自建说明明确提供的是 Docker Web 客户端和后端栈,没有给出商店版/官网版原生客户端切换自建服务器的正式配置流程。社区客户端仅在文末作为未来可选项,本次不安装、不配置。
2. 能实现什么
| 需求 | 本方案 |
|---|---|
| EPUB、PDF、TXT 阅读 | 支持 |
| 书籍文件同步 | 支持,文件存入 MinIO |
| 阅读进度同步 | 支持 |
| 书签、高亮、笔记同步 | 支持 |
| Windows 与 Android 共用书架 | 支持,通过同一自建网页端账户 |
| 全部书籍自动下载到每台设备 | 不会;接收端按需下载 |
| 官方原生 EXE/APK 直接切换自建服务器 | 不作为本方案已验证能力 |
Readest 把一本书拆成两类同步内容:
- 书架条目、封面、元数据、阅读状态、位置、书签、高亮和笔记会同步到登录设备。
- EPUB/PDF/TXT 等实际文件保留在云端,设备打开或主动下载时才获取,不会在后台下载整个书库。
因此,“自动同步书籍”表示书架与云端文件自动保持可用,并不表示每台设备都自动保存完整副本。
Readest 官方支持 EPUB、PDF 和 TXT。EPUB 的排版、目录和批注体验最完整;PDF 的选择、高亮能力取决于 PDF 是否含可用文本层;某些发送或导入路径可能把 TXT 转换为 EPUB,但仍可进入书库并同步。
3. 已核对的官方配置
发布本文前,已逐项对照 Readest 官方仓库 main 分支:
| 项目 | 当前官方值或结论 |
|---|---|
| Compose 文件 | docker/compose.yaml |
| 环境变量模板 | docker/.env.example |
| Nginx 示例 | docker/nginx.conf.example |
| 官方客户端镜像 | ghcr.io/readest/readest:latest |
| Readest Web | 主机端口 3000 |
| Kong / Supabase API | 主机端口 8000 |
| MinIO S3 API | 主机端口 9000 |
| MinIO Console | 主机端口 9001 |
| Supabase 路由 | /auth/v1/、/rest/v1/ |
| 默认 MinIO 存储桶 | readest-files |
| MinIO 反代要求 | 保留原始 Host;上传位置取消请求体大小限制 |
| 自建开关 | SELF_HOSTED=true |
| 更新后迁移 | 运行 zz-readest-migrations.sh |
本文没有沿用旧草案中未经核实的 client_max_body_size 1g;现行官方 Nginx 示例使用 client_max_body_size 0。本文也不使用针对旧版 compose.yaml 的批量 sed 替换,而是用 Docker Compose 官方支持的覆盖文件限制监听地址。
官方资料:
- Readest Docker 自建说明
- Readest Compose 文件
- Readest 环境变量模板
- Readest 官方 Nginx 示例
- Readest 同步与备份文档
- Readest 支持格式与 Web 说明
- Docker Engine 的 Ubuntu 官方安装说明
- Docker Compose
!override说明
main分支会继续变化。部署时记录 Git 提交号,更新前重新检查官方说明和差异。
4. 部署前准备
4.1 建议资源
这不是 Readest 官方硬性最低配置,而是完整数据库与对象存储栈的实用建议:
| 项目 | 建议 |
|---|---|
| Ubuntu | 22.04 LTS、24.04 LTS 或当前受 Docker 支持的 64 位 Ubuntu |
| CPU | 2 核或以上 |
| 内存 | 4 GiB 建议值 |
| 磁盘 | 系统余量至少 10 GiB,另加书库和备份空间 |
| 域名 | 独立子域名,如 read.example.com |
| 公网端口 | TCP 80、443 |
下文统一使用:
| |
执行时必须把 read.example.com 替换为真实域名。
4.2 DNS 和防火墙
在 DNS 服务商处添加:
| 类型 | 主机记录 | 值 |
|---|---|---|
| A | read | 服务器公网 IPv4 |
| AAAA | 可选 | 服务器可用的公网 IPv6 |
如存在错误的 AAAA 记录,应删除或修正,否则部分设备会优先走不可用的 IPv6。
云平台安全组仅需允许 TCP 80、443。不要向公网开放 3000、8000、9000、9001。
Docker 官方提醒:容器发布端口可能绕过 UFW 规则。因此本文把四个容器端口直接绑定到 127.0.0.1,不能只依赖 UFW 阻止外网访问。
4.3 安装基础软件
| |
如果 Docker Engine 和 Compose 插件已经安装,检查版本:
| |
本文的无侵入端口覆盖文件需要 Docker Compose 2.24.4 或更高版本。
4.4 尚未安装 Docker 时
以下命令来自 Docker 当前的 Ubuntu 官方安装方法。已有 Docker 的服务器不要盲目卸载或覆盖,先核对现有安装来源和容器。
| |
确认 Compose 版本不低于 2.24.4,再继续。
5. 下载官方 Readest 项目
| |
DEPLOYED_COMMIT.txt 用于记录本次实际部署的官方源码状态。以后排错或恢复时,不要只写“latest”。
先检查 Docker 目录:
| |
6. 生成并填写环境变量
6.1 复制官方模板
| |
6.2 离线生成随机密钥并写入 .env
Readest 官方要求:
POSTGRES_PASSWORD至少 32 字符且足够随机;JWT_SECRET至少 32 字符;ANON_KEY与SERVICE_ROLE_KEY是由同一个JWT_SECRET使用 HS256 签名的 JWT;ANON_KEY的 payload 为{"role":"anon"};SERVICE_ROLE_KEY的 payload 为{"role":"service_role"};MINIO_ROOT_PASSWORD使用强随机密码。
下面的本地 Python 辅助脚本不联网、不安装第三方包,只按上述官方规则生成并更新已复制的模板。运行前先设置真实域名:
| |
STORAGE_FIXED_QUOTA=10737418240表示每用户逻辑配额 10 GiB,不会自动扩大服务器磁盘。可按实际容量修改。
6.3 人工复核非秘密项
不要把 .env 全文粘贴到工单、聊天或公开仓库。只检查必要的非秘密值:
| |
预期域名相关值全部指向同一个 HTTPS 源:
| |
不要公开:
POSTGRES_PASSWORDJWT_SECRETSERVICE_ROLE_KEYMINIO_ROOT_PASSWORD- 完整
.env
ANON_KEY 会由网页客户端使用,但仍应从服务器配置中复制,不应随意替换;SERVICE_ROLE_KEY 具有高权限,绝不能放入客户端设置或公开页面。
7. 仅在本机发布容器端口
官方 compose.yaml 默认发布 3000、8000、9000、9001。官方 Nginx 示例建议在反代部署中绑定到回环地址。
为了保留官方 compose.yaml 原样并便于更新,创建 docker/compose.override.yaml:
| |
写入:
| |
!override 需要 Docker Compose 2.24.4 或更高版本。不要删除这个标记,否则 Compose 可能把新旧端口列表合并,重新暴露公网端口。
验证合并配置:
| |
在完整输出的 ports 项中,应看到 host_ip: 127.0.0.1。如果 docker compose config 报不认识 !override,先升级 Compose 插件,不要启动服务。
8. 启动官方 Compose 栈
| |
查看关键日志:
| |
minio-setup 是一次性创建存储桶的辅助容器,成功执行后退出是正常现象。其余长期服务应处于运行状态;MinIO 健康检查应通过。
检查监听地址:
| |
所有匹配项都应只监听 127.0.0.1,不应出现 0.0.0.0、[::] 或公网 IP。
在服务器本机测试 Web 客户端:
| |
9. 配置 Nginx 和 HTTPS
9.1 先配置 HTTP 证书验证站点
| |
先写入以下临时配置,并替换域名:
| |
启用站点:
| |
如果符号链接已存在,不要重复创建;直接继续检查配置即可。
从外网确认 http://read.example.com 能访问后申请证书:
| |
证书通常位于:
| |
9.2 写入最终 HTTPS 反向代理
| |
用下面的完整配置替换临时配置。该路由结构与 Readest 官方 Nginx 示例一致:
| |
关键点:
/auth/v1/和/rest/v1/必须转发到 Kong 的 8000。/readest-files/必须转发到 MinIO 的 9000。- 路径首段
readest-files必须与S3_BUCKET_NAME一致。 - MinIO 的预签名 URL 会校验 Host,不能在代理中改成其他主机名。
client_max_body_size 0是官方示例的当前写法,用于避免大文件上传被 Nginx 截断。- MinIO Console 的 9001 不需要公网 Nginx 路由。
应用并验证:
| |
第二条命令用于确认 Auth 路由能够到达后端;重点是不能出现 Nginx 404、502 或 TLS 错误。
检查证书续期:
| |
10. 首次注册和关闭公开注册
10.1 创建第一个账户
在 Windows 浏览器打开:
| |
使用邮箱和强密码注册。这个账户属于你的自建服务,与 Readest 官方云账户不是同一套账户数据。
本文默认:
| |
因此无需邮件确认即可建立首个账户。由于没有配置 SMTP,密码重置邮件通常也不可用,务必把账户密码和服务器备份妥善保存。
10.2 注册完成后立即关闭公开注册
| |
改为:
| |
应用:
| |
使用浏览器无痕窗口尝试注册新账户,确认注册已被拒绝;现有账户登录应保持正常。
如果将来需要多用户:
- 临时打开注册或配置 SMTP;
- 创建所需账户;
- 再次关闭注册;
- 不要长期保留“自动确认 + 公开注册”。
11. 启用 EPUB/PDF/TXT 与阅读数据同步
登录后进入:
| |
确认启用:
Books:书籍文件与书架元数据;Reading Progress:最后阅读位置、书签和每本书的偏好;Annotations:高亮与笔记。
建议用三本小型测试文件验收:
- Windows 端导入 1 本 EPUB、1 个含文本层的 PDF、1 个 TXT。
- 等待同步完成,刷新书架。
- Android 端登录同一账户。
- 确认三本书的书架条目和封面出现。
- 分别打开书籍,让设备按需下载文件。
- 在 Windows 端改变阅读位置并创建书签、高亮、笔记。
- Android 端重新打开相同书籍,验证位置和批注。
- 在 Android 端新增笔记,再回到 Windows 验证双向同步。
不要只根据“封面出现”判断同步成功;封面、条目、实际书籍文件和批注是不同的数据层。
12. Windows 和 Android 使用方式
12.1 Windows
推荐 Edge 或 Chrome:
- 打开
https://read.example.com。 - 登录自建账户。
- 浏览器地址栏或菜单出现“安装应用”时选择安装。
- 没有安装入口时,创建站点快捷方式并固定到任务栏或开始菜单。
- 第一次离线使用前,先在线打开网页和需要离线阅读的书籍。
12.2 Android
- 用 Chrome 打开
https://read.example.com。 - 登录同一自建账户。
- 菜单中有“安装应用”时选择安装;否则选择“添加到主屏幕”。
- 在线打开需要离线阅读的书,使文件缓存到设备。
- 断网测试已下载书籍能否打开。
浏览器和系统可能回收站点存储。重要书籍不要只保留在手机浏览器缓存中,服务器备份才是长期副本。
13. 迁移现有 Readest 数据
在原有 Readest 中进入:
| |
导出完整 ZIP。官方文档说明,书库备份可包含书籍文件、元数据、阅读状态、分组、高亮、笔记和应用设置。
迁移原则:
- 不要先卸载原客户端或清理原数据。
- 在自建网页端先导入少量备份,验证书籍、位置和笔记。
- 确认 Windows 与 Android 双端同步正常后,再迁移完整书库。
- 备份默认不加密;只有确有需要时才选择包含账户凭据,并把文件放入加密存储。
自建账户与官方云账户相互独立,不能假设登录自建站点后原官方云书库会自动出现。
14. 备份策略
至少保留两层备份:
- Readest 应用内 ZIP:便于用户级迁移和快速恢复。
- 服务器冷备份:保存数据库卷、MinIO 卷、配置卷、
.env和 Nginx 配置。
建议采用 3-2-1 原则:至少 3 份副本、2 种介质、1 份异地。
14.1 确认卷名
官方 compose.yaml 顶层项目名是 readest,通常创建:
| |
备份前仍应实际检查:
| |
14.2 一致性冷备份
下面会短暂停止 Readest。先确认备份磁盘空间充足:
| |
开始备份:
| |
注意:
- 如果任何备份命令失败,也要执行
sudo docker compose start恢复服务。 - 首次运行会拉取官方
alpine工具镜像。 .env和数据库备份含高敏感密钥与账户数据,异地保存前必须加密。- 定期做恢复演练;只有成功恢复过的备份才算可靠。
- 永远不要把
docker compose down -v当作普通停止命令,它会删除数据卷。
14.3 恢复思路
恢复应在全新或已确认可覆盖的目标环境中进行:
- 安装 Docker、Nginx,恢复与备份一致的 Readest Git 提交。
- 恢复
docker/.env、compose.override.yaml和 Nginx 配置。 - 在未启动 Readest 前创建三个同名卷。
- 用临时 Alpine 容器把各
tar.gz解压到对应空卷。 - 启动 Compose,检查数据库、登录、书籍与批注。
- 如恢复到新域名,必须同步修改
SITE_URL、API_EXTERNAL_URL、ADDITIONAL_REDIRECT_URLS、SUPABASE_PUBLIC_URL、S3_PUBLIC_ENDPOINT和 Nginx 证书/域名。
不要把恢复操作直接用于仍有有效数据的生产卷;先在测试机演练。
15. 更新流程
更新前先做完整备份,并阅读 Readest Release Notes 与 docker/README.md。
查看本地状态和官方 Docker 文件差异:
| |
确认差异后更新源码:
| |
更新容器并执行官方数据库迁移:
| |
官方说明指出:拉取新版客户端镜像不会自动修改已有数据库卷,而首次启动钩子只在空数据库卷运行,因此已有部署升级后必须手动运行迁移脚本。脚本会记录已应用迁移,正常情况下可重复执行。
生产环境可把 READEST_IMAGE 从滚动的 latest 改为官方发布的具体版本标签,先在测试环境验证后再升级。不要使用来源不明的镜像。
16. 日常检查与排错
16.1 状态和日志
| |
16.2 常见症状
网页出现 502
| |
登录或注册失败
| |
书籍上传失败或签名错误
重点核对:
S3_PUBLIC_ENDPOINT=https://read.example.com;S3_BUCKET_NAME=readest-files;- Nginx 路径为
/readest-files/; - MinIO 位置保留
proxy_set_header Host $host;; client_max_body_size 0;;- 没有 CDN、WAF 或上游代理改写 Host、路径或限制请求体。
端口意外暴露公网
| |
如果发现 0.0.0.0 或 [::],先停止栈,修复 compose.override.yaml,确认 Compose 版本支持 !override 后再启动。
中文或日文字体加载失败
官方 README 说明:部分 CJK Web 字体默认来自 Readest CDN,而 CDN 的 CORS 只允许 readest.com 来源。自定义域名如需这些字体,应把相应字体包镜像到自己的域名,并设置:
| |
这是可选项;系统字体和 Google Fonts 不受此设置影响。不要从不可信来源下载字体文件。
17. 安全清单
- 只对公网开放 80、443。
- 3000、8000、9000、9001 只监听
127.0.0.1。 - 使用有效 HTTPS 证书并测试自动续期。
-
POSTGRES_PASSWORD、JWT_SECRET、SERVICE_ROLE_KEY、MINIO_ROOT_PASSWORD均为随机强密钥。 -
docker/.env权限为 600。 - 首个账户创建后已设置
DISABLE_SIGNUP=true。 - 没有把 MinIO Console 9001 代理到公网。
- 没有把
SERVICE_ROLE_KEY填到任何客户端或社区程序。 - 不执行
docker compose down -v。 - 更新前做冷备份,更新后执行官方迁移脚本。
- 备份已加密并有异地副本。
- 至少做过一次测试恢复。
- 定期检查磁盘、证书、容器健康状态和官方安全更新。
需要临时访问 MinIO Console 时,优先使用 SSH 隧道,而不是公开 9001:
| |
然后在本机打开 http://127.0.0.1:9001。结束后关闭 SSH 会话。
18. 验收清单
-
https://read.example.com证书有效。 - HTTP 自动跳转 HTTPS。
-
/auth/v1/health能到达 Auth 后端。 - 新账户可登录。
- 关闭注册后不能再创建新账户。
- EPUB 可上传、打开、跨端按需下载。
- PDF 可上传、打开、同步阅读位置。
- TXT 可导入、打开、跨端获取。
- 阅读进度双向同步。
- 书签、高亮、笔记双向同步。
- 手机离线可打开已经下载的书。
- 3000、8000、9000、9001 没有公网监听。
- 应用内 ZIP 已导出。
- 服务器冷备份已生成并校验。
19. 未来可选:社区客户端
如果以后必须使用可配置自建服务器的 Windows/Android 原生客户端,可以单独评估社区项目:
该项目不是 Readest 官方发行版。本次正式部署不安装、不下载、不填写任何服务器密钥到社区客户端。
未来评估时至少检查:
- 最近提交和发行时间;
- 是否跟上官方数据库结构与同步协议;
- 构建产物来源和签名;
- 是否只需要公开的
ANON_KEY,绝不能要求SERVICE_ROLE_KEY、数据库密码或 JWT Secret; - 先用测试账户和少量测试书验证;
- 保留官方自建网页端作为可回退入口。
在完成上述审计前,不建议用社区客户端替换现有正式阅读环境。
附录:正式部署范围摘要
本指南正式启用:
- Readest 官方 GitHub 仓库;
- Readest 官方 GHCR 镜像;
- 官方 Docker Compose 后端栈;
- Nginx 单域名 HTTPS;
- 官方自建网页端;
- 浏览器提供时的 PWA/站点安装;
- EPUB、PDF、TXT 文件与阅读数据同步;
- 应用内备份和服务器冷备份。
本指南暂不启用:
- 社区改版 Windows 客户端;
- 社区改版 Android 客户端;
- BookOrbit、Grimmory 等社区服务;
- 外部 WebDAV/S3 作为第二同步层;
- 对公网开放 MinIO Console;
- 未经官方仓库验证的 Compose、环境变量或 Nginx 路由。
