部署 教程

5 分钟完成部署,从 Docker 安装到上线运行,按顺序跟做即可。

v8.12.2 最新功能: 防御性文件名生成 + 更好的上传/下载错误诊断。即使未来代码回归导致 getStorageTypebook.format/book.title 异常,getRemoteBookFilename 也永不返回空串(兑底用 book.hash 作文件名)· 上传失败响应体新增 hint + received 字段 · 下载失败响应体新增 hint + receivedFileKey 字段 · 放宽 download fallback 的 parts.length 检查。
v8.12.1:紧急修复 v8.12.0 上游同步误覆盖 Lite 自定义代码:① 下载书籍报 "File not found"(getRemoteBookFilename 在 'local' 存储类型返回空串 → fileKey 缺文件名段);② 「关于」按钮弹出官方 Readest 页面(AboutWindow 被覆盖成上游版本)。
v8.12:上游 Readest v0.11.17 全量同步(逐文件对比,163 个安全文件直接复制 + 21 个新文件添加 + 58 个 Lite 自定义文件保留不覆盖)· 排除 Google Drive/payment/tests · 手动同步 30+ 个类型字段。
v8.11:合并上游 v0.11.17 功能:Markdown (.md) 文件渲染 · PDF/CBZ 对比度选项 · TTS 高亮粒度(单词/句子)· 最近阅读书架 · 自动翻页角落区域 50px 上限 · 清理空高亮 · foliate-js 自动更新(PDF pinch-zoom/翻页性能)。
v8.10.4:恢复跨设备视图设置同步(用户中心 → Manage Sync → View Settings toggle,默认关)。
v8.10.3:登出后隐藏全部书籍(修复 demo books 残留)· 移出分组不再踢出用户。
v8.10.2:笔记导出链接绝对 URL(站外可点击)· Reader 书不在库里时自动重试加载 · 用户管理折叠。
v8.10.1:批量下载 per-URL Cookie/Headers 语法(URL | cookie:VALUE | header:Key: VALUE)。
v8.10:中文汉化(zh-CN + zh-TW 补全 60 个翻译 key)· 笔记导出链接手机默认走 web reader · 登出后清空残留 library.json · 阅读统计(总/今日/本周 + 书榜)· 下载记录折叠。
v8.9:下载任务大增强:进度条/速度/ETA/用时 · 点击任务看完整日志 · 批量下载 · 自动重命名 · Cookie/Headers 高级选项。
v8.8:分块上传规避 Cloudflare 524 超时(大文件自动切 5MB · 服务端流式合并 · 小文件零变化)。
v8.7:跨设备下载任务队列(DownloadTask 表落库 · 用户中心面板 · 5s 轮询 · 暂停/恢复/重试 · 批量操作)。
v8.6:合并上游 Readest 0.11.12 · 图片保存按钮 · 分享永久(∞)+自定义有效期 · 远程下载任务队列 · 安卓自编译源码
v8.5:配额真正 enforce · 真实配额 UI · SSRF 黑名单 · fire-and-forget 下载。
v8.4:Per-user 加密 vault(AES-GCM + 服务端托管密钥)。
v8.3:账号切换数据隔离。
v8.2:代理开关 · 全站 Readest Lite 品牌。
v8.1:远程下载写 Book 表 · ADMIN_USERNAME env。
v8.0:所有翻译/词典代理强制登录。
v7.0:多用户管理 · 远程书籍下载 · Edge TTS · 字体本地化。

环境准备

只需要 Docker,无需安装 Node.js 或数据库。

安装 Docker

# 一键安装 Docker
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER
sudo systemctl enable --now docker

# 验证
docker --version
安装后需重新登录终端或执行 newgrp docker 使权限生效。macOS 推荐 Docker Desktop。

快速开始

一条命令拉起,30 秒后访问 http://localhost:8225

docker run -d \
  --name readest-lite \
  -p 8225:8225 \
  -v readest-data:/data \
  -e ADMIN_EMAIL=admin@example.com \
  -e ADMIN_PASSWORD=changeme \
  -e ADMIN_USERNAME=Admin \
  -e PUBLIC_BASE_URL=https://read.yourdomain.com \
  --restart unless-stopped \
  ghcr.io/cshdotcom/readest-lite:latest
请务必修改默认密码,生产环境使用 16 位以上随机字符串。

CLI 方式环境变量说明

通过 docker run -e 传递,常用 env:

指定特定版本:ghcr.io/cshdotcom/readest-lite:v8.12.2(每个版本都有对应 git tag,详见 GitHub Releases)。

Docker Compose 部署(推荐)

配置清晰、升级方便、重启自动恢复,适合长期运行。

docker-compose.yml

version: "3.8"
services:
  readest-lite:
    image: ghcr.io/cshdotcom/readest-lite:latest
    container_name: readest-lite
    restart: unless-stopped
    ports:
      - "${PORT:-8225}:8225"
    volumes:
      - ./data:/data
    environment:
      - ADMIN_EMAIL=${ADMIN_EMAIL}
      - ADMIN_PASSWORD=${ADMIN_PASSWORD}
      - PUBLIC_BASE_URL=${PUBLIC_BASE_URL:-}
      - DEEPL_ENABLED=${DEEPL_ENABLED:-false}

.env

ADMIN_EMAIL=admin@example.com
ADMIN_PASSWORD=your-secure-password
PORT=8225
# 可选:反向代理场景必填
PUBLIC_BASE_URL=https://read.yourdomain.com
# 可选:翻译功能(默认关闭)
DEEPL_ENABLED=false
DEEPL_FREE_API_KEYS=
DEEPL_PRO_API_KEYS=

常用命令

docker compose up -d       # 启动
docker compose ps           # 状态
docker compose logs -f      # 日志
docker compose down          # 停止
restart: unless-stopped 确保容器在 Docker 重启或意外退出后自动恢复。

环境变量

容器启动时读取,修改后需重启生效。

变量必填默认说明
ADMIN_EMAIL必填管理员邮箱,首次启动自动创建账号
ADMIN_PASSWORD必填管理员密码,建议 16+ 位随机字符串
ADMIN_USERNAME可选v8.1 新增:管理员显示名,用户列表里展示用。未设置时回退到邮箱
PUBLIC_BASE_URL可选http://localhost:8225对外访问 URL,反向代理/分享场景必填。例如 https://read.yourdomain.com
PORT可选8225容器内监听端口,一般不需修改
DEEPL_ENABLED可选false设为 true 启用 DeepL 翻译,需配合 DEEPL_FREE_API_KEYS 或 DEEPL_PRO_API_KEYS
JWT_SECRET可选派生JWT 密钥,不设置时由 ADMIN_EMAIL + ADMIN_PASSWORD 派生
.env 加入 .gitignore,避免密码泄露到版本控制。

数据持久化

所有数据存储在容器 /data 目录,通过卷挂载确保容器重建不丢失。

目录结构

data/ ├── db/ SQLite 数据库 │ └── readest.db 用户、书籍、进度、批注 ├── books/ 书籍文件 │ ├── uploads/ 上传的电子书 │ └── covers/ 自动生成的封面 └── config.json 运行时配置(自动生成)

备份

# 停止容器后打包
tar czf readest-backup-$(date +%Y%m%d).tar.gz data/

# 保留最近 30 天
find . -name "readest-backup-*.tar.gz" -mtime +30 -delete
备份前建议先停止容器,避免 SQLite 在写入中被打包出损坏的文件。

反向代理

生产环境推荐通过反向代理暴露到公网,并配置 HTTPS。

Nginx

server {
    listen 443 ssl http2;
    server_name read.yourdomain.com;

    ssl_certificate     /path/to/fullchain.pem;
    ssl_certificate_key /path/to/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:8225;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;

        # WebSocket(同步功能必需)
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_read_timeout 86400;
    }
}

Caddy(更简单)

read.yourdomain.com {
    reverse_proxy localhost:8225
}
Caddy 自动申请和续期 HTTPS 证书,零配置。确保域名 DNS 已解析到服务器且 80/443 端口开放。

升级更新

定期升级获取最新功能与修复,数据不受影响。

# 拉取最新镜像
docker compose pull

# 重建容器(数据在 ./data 不受影响)
docker compose up -d

# 清理旧镜像
docker image prune -f
启动时自动检测数据库版本并执行迁移,无需手动操作。

多用户管理

管理员可以在用户中心创建和管理普通用户。

创建用户

  1. 管理员登录后进入「用户中心」
  2. 在「用户管理」面板点击「新建用户」
  3. 填写邮箱、密码、显示名称
  4. 设置存储配额(MB)和翻译配额(KB),0 = 无限
  5. 点击创建,用户即可用邮箱密码登录
普通用户登录后看不到用户管理面板,只能查看自己的账号信息。管理员可以编辑任何用户的密码、名称和配额,也可以删除非管理员用户。

常见问题

启动后无法访问?

  1. docker ps 确认容器状态为 Up
  2. curl http://localhost:8225 在服务器本地测试
  3. 检查防火墙:sudo ufw allow 8225
  4. docker logs readest-lite 查看错误日志

如何修改密码?

修改 .env 中的 ADMIN_PASSWORD,然后 docker compose down && docker compose up -d

如何换端口?

修改 docker-compose.yml 端口映射:"9000:8225"(左边是对外端口)。

书籍存在哪里?

data/books/uploads/ 存书籍原文,data/books/covers/ 存封面图,容器重建不丢失。

支持多用户吗?

支持!管理员登录后在「用户中心」可以看到「用户管理」面板,可以创建普通用户、设置用户名密码、分配存储和翻译配额。普通用户登录后只能看到自己的账号信息,没有管理权限。

切换账号后,原来账号的书会泄露吗?

v8.3 起不会。登出时系统会彻底清空当前账号的:

登录新账号后,系统走全量 pull(since=0),只拉取新账号的云端书。本地 Books/ 目录下的书籍文件保留(不删),但不会出现在新账号的书库列表里——除非新账号的云端也有同 hash 的书。

未登录时导入的书:如果你没登录就导入了书,登录账号后这些书会自动同步到当前登录的账号(不会被清空)。

如何使用远程下载?

在书库页面点击「导入」→「Download from URL」,输入书籍直链地址(如 https://example.com/book.epub)。v8.1 修复了书架不显示问题:下载完成后服务器同时写入 Book 表,新书会出现在书库中,多端 sync 同步可见。

翻译和词典需要登录吗?

v8.0 起所有翻译/词典代理强制要求登录,包括:

未登录调用返回 401。客户端无需加速器:只要服务器能访问 Google,前端通过代理就能用。

浏览器直接访问 /api/translate/google 显示"认证失败"是 bug 吗?

不是 bug,是预期行为。翻译/词典代理是 POST 接口,需要 Authorization: Bearer <token> 头。浏览器地址栏直接 GET 访问不会带这个头,所以返回 401 "Authentication required"。

v8.2 给三个代理路由加了 GET health check,返回带 hint 字段的 JSON,告诉你如何用 curl 测试:

# 测试 Google 翻译代理(替换 YOUR_TOKEN 和 your-host)
curl -H "Authorization: Bearer YOUR_TOKEN" \
  -X POST -H "Content-Type: application/json" \
  -d '{"text":["hello"],"targetLang":"zh"}' \
  https://your-host/api/translate/google

# 测试 Wikipedia 代理
curl -H "Authorization: Bearer YOUR_TOKEN" \
  "https://your-host/api/proxy/wiki?url=https://en.wikipedia.org/api/rest_v1/page/summary/Hello"

在应用内正常使用(选中文字 → 翻译/词典按钮)会自动带 token,不需要手动操作。

v8.2 代理开关怎么用?

登录后进入「设置 → Integrations → Network」,有「Server Proxy」开关:

注意:Edge TTS 不受此开关影响(始终保持 wss 直连 + https 代理降级行为)。DeepL 也不受影响(API key 在服务器,必须走代理)。

100TB 配额是硬限制吗?

不是。100TB 是前端展示用的软上限,实际不强制执行——上传代码不查配额,真正的限制只有宿主机磁盘空间。管理员在用户管理面板设置的 storageQuotaMB 字段当前为展示型(v8.3 计划补上 enforce 逻辑)。

翻译和词典需要加速器吗?

不需要(代理开启时)。Google 翻译、Wikipedia、Wiktionary 都通过服务器代理访问。只要服务器能访问 Google(如国外 VPS),客户端无需加速器即可使用。如果关了代理开关,客户端需要自己能访问这些站点。

如何启用 DeepL 翻译?

.env 中设置 DEEPL_ENABLED=trueDEEPL_FREE_API_KEYSDEEPL_PRO_API_KEYS,重启容器即可。

如何迁移数据?

直接复制整个 data/ 目录到新服务器,用相同参数启动容器即可。SQLite 文件可跨平台使用。