docs: split bilingual readme and getting started guides

This commit is contained in:
hectorqin committed 2026-09-22 17:12:49 +08:00
1 parent 4af639d3b8
commit 5772014d3f
10 files changed
+864 -660

No files matched your search

+38
View File
@@ -0,0 +1,38 @@
# 文档中心 · Documentation
[项目首页](../README.md) · [English overview](../README.en.md)
项目首页介绍用途与能力;安装、日常使用、运维和开发步骤分别放在下面的指南中。
The project README introduces reader. Use the guides below for installation, everyday use, operations, and development.
## 使用与部署 · Using and deploying reader
| 内容 / Topic | 简体中文 | English |
| --- | --- | --- |
| 安装、首次登录、添加书籍、更新 / Installation and first steps | [入门指南](getting-started.zh-CN.md) | [Getting started](getting-started.en.md) |
| 书架、阅读、朗读、来源和离线 / Shelves, reading, TTS, sources, offline | [使用手册](user-guide.zh-CN.md) | Chinese only |
| 环境变量、目录权限、HTTPS、排错 / Settings, permissions, HTTPS, troubleshooting | [部署配置](configuration.zh-CN.md) | [Configuration](configuration.en.md) |
| 本地开发、验证、镜像与 Android 构建 / Development, checks, Docker and Android builds | [开发指南](development.zh-CN.md) | [Development](development.en.md) |
## 技术参考 · Technical reference
以下参考文档目前以中文维护。The following reference documents are currently maintained in Chinese.
| 文档 / Document | 内容 / Contents |
| --- | --- |
| [架构与数据边界 / Architecture](architecture.md) | 数据目录、身份、同步和客户端架构 / Data boundaries, identity, sync, client architecture |
| [API](api.md) | 鉴权、书籍、资源、进度、文件管理、来源 / Auth, books, resources, progress, file management, sources |
| [来源插件系统 / Source plugins](source-plugins.md) | 契约、宿主职责及实施状态 / Contracts, host responsibilities, implementation status |
| [通用插件扩展 / Plugin extensions](plugin-extensions.md) | 配置页面、任务、搜索、换源 / Configuration pages, tasks, search, source switching |
| [界面规范 / UI guidelines](ui.md) | 布局、交互、可访问性 / Layout, interaction, accessibility |
## 验证记录 · Review records
这些是特定功能交付时的验证记录,当前结果以对应提交的测试和 CI 输出为准。
These records describe checks at specific delivery points. Use tests and CI for the current commit's results.
- [UI 评审工具 / UI review tooling](ui-review/README.md)
- [书源界面 / Source UI](ui-review/sources-ux.md)
- [书库与阅读界面 / Library and reader UI](ui-review/collections-ux.md)
- [书源搜索 / Source search](ui-review/source-search.md)
- [搜索性能 / Search performance](ui-review/source-search-performance.md)
+95
View File
@@ -0,0 +1,95 @@
# Configuration
[Project home](../README.en.md) · [Documentation](README.md) · [简体中文](configuration.zh-CN.md)
For a first installation, follow [getting started](getting-started.en.md). This page covers configuration, maintenance, and troubleshooting.
## Directories and permissions
- `BOOKS_DIR` contains your books. Use `:ro` for read-only access, or `:rw` plus filesystem write permissions for administrator file management.
- `DATA_DIR` stores SQLite, accounts, reading records, keys, covers, scan state, upload staging, remote downloads, and plugin data. It must always be writable.
- `DATA_DIR` must not be the same directory as, or a child of, `BOOKS_DIR`. Startup rejects that configuration.
- The image entrypoint attempts to fix ownership of the data directory itself, then runs as the `reader` user. It does not change book-directory ownership or recursively repair existing data-file permissions.
Read-only books do not prevent account or progress updates in the data directory. To enable uploads, check host ACLs and directory permissions as well as changing the mount to `:rw`.
## Environment variables
These are defaults when running the server directly. The Docker image additionally sets `DATA_DIR=/data` and `WEB_DIR=/app/web`, with `BOOKS_DIR=/books`.
| Variable | Default | Purpose |
| --- | --- | --- |
| `BOOKS_DIR` | `/books` | Book directory |
| `DATA_DIR` | `data` under the current working directory | Server state and caches |
| `HOST` | `0.0.0.0` | Listen address |
| `PORT` | `8080` | Listen port |
| `PUBLIC_URL` | Empty | Public-facing URL; set when using a reverse proxy |
| `SCAN_INTERVAL` | `1800` | Scheduled scan interval in seconds; `0` disables it |
| `WATCH_INTERVAL` | `60` | Change-check interval in seconds; `0` disables it |
| `ALLOW_REGISTRATION` | `false` | Allow public registration after the first account |
| `ACCESS_TOKEN_TTL` | `86400` | Access-token lifetime in seconds |
| `REFRESH_TOKEN_TTL` | `31536000` | Refresh-token lifetime in seconds |
| `READER_TOKEN_SECRET` | Generated | Signing secret, at least 16 characters; otherwise stored in `DATA_DIR/token.secret` |
| `LOG_LEVEL` | `info` | Logging level |
| `CORS_ORIGINS` | Empty | Comma-separated browser origins; empty reflects the requesting origin |
| `WEB_DIR` | `web` under the current working directory | Built Web client directory |
| `TTS_URL` | Empty | HTTP speech upstream; empty disables HTTP speech |
| `TTS_TOKEN` | Empty | Upstream Bearer token |
| `TTS_VOICES_URL` | `<TTS_URL>/voices` | Upstream voice list |
| `TTS_TIMEOUT_MS` | `20000` | Speech request timeout in milliseconds |
| `TTS_CACHE_BYTES` | `268435456` | Byte limit for `DATA_DIR/tts-cache`; `0` disables caching |
Run `docker compose up -d` after changing environment variables. Keep the signing secret stable to preserve sessions. Accounts, progress, and notes cannot be recovered by rescanning book files.
## HTTPS and reverse proxies
Use `http://<server-ip>:8080` on your LAN. Use HTTPS for public access to protect login credentials and access tokens.
For Caddy running on the same host as reader:
```caddyfile
reader.example.com {
reverse_proxy 127.0.0.1:8080
}
```
Set `PUBLIC_URL=https://reader.example.com`. If Caddy also runs in a container, use reader's service address on the container network instead.
For separately hosted frontends, set `CORS_ORIGINS` to the Web client's actual origin. Source search uses Streamable HTTP: proxies must forward `text/event-stream` incrementally rather than buffer the entire response. A VPN or tunnel can provide access when you have no public IP.
## HTTP text-to-speech
Use Android system speech or browser `speechSynthesis` when available. To enable an HTTP speech service, configure a compatible upstream in Compose:
```yaml
environment:
TTS_URL: "http://your-tts-host:5002/tts"
# TTS_TOKEN: "your-token"
# TTS_VOICES_URL: "http://your-tts-host:5002/voices"
TTS_CACHE_BYTES: "268435456"
```
reader proxies speech requests and does not include a synthesis model. The upstream must implement the expected request protocol; a service's name alone does not establish compatibility. See the [TTS API (中文)](api.md). The address must be reachable from the reader container; `localhost` inside a container refers to that container.
## Troubleshooting
### Data directory is not writable at startup
Check `docker compose logs --tail=100 reader`. For `EACCES` on `/data/token.secret`, the database, or caches:
1. Confirm `/data` is writable and has free space.
2. If you set `user:`, `--user`, or replace the entrypoint, ensure that user can write the data directory.
3. Run `docker compose run --rm --no-deps --entrypoint id reader reader` to inspect the image's `reader` UID/GID, then correct host directory ownership or ACLs. If you use a custom runtime user, use that user's identity instead.
4. NFS, SMB, and NTFS may need their own permission configuration rather than `chown` alone.
Setting `READER_TOKEN_SECRET` only avoids writing the secret file. It does not remove the need for writable database and cache storage.
### File management returns `READ_ONLY_MOUNT`
Check whether the mount uses `:ro`. After switching to `:rw` and recreating the container, verify the server process can write the target directory. Uploads are available only on the administrator file-management page.
### The UI opens but books are missing
Check that the mounted files are readable and supported, then wait for scanning or trigger a scan as an administrator. The scanner skips directories such as `.git`, `@eaDir`, and `#recycle` and does not follow symlinks. Use the library file page to inspect the actual directory.
### Remote source searches fail
+95
View File
@@ -0,0 +1,95 @@
# 部署配置
[项目首页](../README.md) · [文档中心](README.md) · [English](configuration.en.md)
初次部署请先看[入门指南](getting-started.zh-CN.md)。本页适用于部署后的配置、维护与排错。
## 目录与权限
- `BOOKS_DIR` 是用户书籍目录。`:ro` 用于只读部署;`:rw` 配合文件系统写权限启用管理员文件管理。
- `DATA_DIR` 保存 SQLite、账号、阅读记录、密钥、封面、扫描状态、上传暂存、远程下载与插件数据,必须始终可写。
- `DATA_DIR` 不能与 `BOOKS_DIR` 相同或位于其内部,启动时会拒绝该配置。
- 镜像入口脚本尝试修正数据目录本身的属主,再以 `reader` 用户运行。它不会替你修改书籍目录的属主,也不会递归修复已有数据文件的权限。
书库只读不影响账号和阅读进度写入数据目录。需要上传时,除修改 `:rw` 外,还要检查宿主机 ACL 或目录权限。
## 环境变量
以下是直接运行服务端时的默认值。Docker 镜像另设 `DATA_DIR=/data`、`WEB_DIR=/app/web`,`BOOKS_DIR=/books`。
| 变量 | 默认值 | 用途 |
| --- | --- | --- |
| `BOOKS_DIR` | `/books` | 书籍目录 |
| `DATA_DIR` | 当前工作目录下的 `data` | 服务端状态和缓存目录 |
| `HOST` | `0.0.0.0` | 监听地址 |
| `PORT` | `8080` | 监听端口 |
| `PUBLIC_URL` | 空 | 对外访问地址,反向代理后设置 |
| `SCAN_INTERVAL` | `1800` | 定时扫描间隔,秒;`0` 关闭 |
| `WATCH_INTERVAL` | `60` | 变化检查间隔,秒;`0` 关闭 |
| `ALLOW_REGISTRATION` | `false` | 首个账号之后是否允许公开注册 |
| `ACCESS_TOKEN_TTL` | `86400` | 访问令牌有效期,秒 |
| `REFRESH_TOKEN_TTL` | `31536000` | 刷新令牌有效期,秒 |
| `READER_TOKEN_SECRET` | 自动生成 | 至少 16 字符的签名密钥;默认保存在 `DATA_DIR/token.secret` |
| `LOG_LEVEL` | `info` | 日志级别 |
| `CORS_ORIGINS` | 空 | 允许的浏览器来源,逗号分隔;空值反射请求来源 |
| `WEB_DIR` | 当前工作目录下的 `web` | 已构建 Web 客户端目录 |
| `TTS_URL` | 空 | HTTP 语音上游地址,空值关闭 HTTP 朗读 |
| `TTS_TOKEN` | 空 | 上游 Bearer 令牌 |
| `TTS_VOICES_URL` | `<TTS_URL>/voices` | 上游语音列表 |
| `TTS_TIMEOUT_MS` | `20000` | 单次语音请求超时,毫秒 |
| `TTS_CACHE_BYTES` | `268435456` | `DATA_DIR/tts-cache` 缓存上限,字节;`0` 关闭 |
修改 Compose 环境变量后执行 `docker compose up -d`。签名密钥需要稳定保存,否则已有会话会失效。数据目录中的账号、进度和笔记不能靠重新扫描书籍恢复。
## HTTPS 与反向代理
局域网可直接访问 `http://<服务器IP>:8080`。对公网提供服务时使用 HTTPS,保护登录凭据和访问令牌。
例如 Caddy 与 reader 运行在同一台主机上时:
```caddyfile
reader.example.com {
reverse_proxy 127.0.0.1:8080
}
```
设置 `PUBLIC_URL=https://reader.example.com`。如果 Caddy 也在容器中,代理地址应改为容器网络中 reader 的服务地址。
前后端分开部署时,将 `CORS_ORIGINS` 设置为 Web 客户端的实际来源。书源搜索采用 Streamable HTTP,代理需要持续转发 `text/event-stream`;不要把搜索响应缓冲到完成后才返回。没有公网 IP 时也可用 VPN 或隧道连接服务。
## HTTP 朗读
优先使用 Android 系统语音或浏览器 `speechSynthesis`。需要 HTTP 语音时,在 Compose 中配置兼容上游:
```yaml
environment:
TTS_URL: "http://your-tts-host:5002/tts"
# TTS_TOKEN: "your-token"
# TTS_VOICES_URL: "http://your-tts-host:5002/voices"
TTS_CACHE_BYTES: "268435456"
```
reader 代理语音请求,不内置合成模型。上游接口需兼容项目的请求协议;不能仅凭服务名称判断是否兼容,详见 [TTS API](api.md)。地址必须从 reader 容器内可达,容器内的 `localhost` 指容器自身。
## 故障排查
### 启动时报数据目录不可写
先看 `docker compose logs --tail=100 reader`。如果是 `/data/token.secret`、数据库或缓存目录的 `EACCES`:
1. 检查 `/data` 没有被只读挂载,且有可用空间。
2. 若设置了 `user:`、`--user` 或替换了入口脚本,需要自行保证该用户可写数据目录。
3. 运行 `docker compose run --rm --no-deps --entrypoint id reader reader` 查看镜像中 `reader` 用户的 UID/GID,再在宿主机修正该数据目录的属主或 ACL;自定义运行用户时以该用户为准。
4. NFS、SMB 或 NTFS 需按共享文件系统的权限机制配置,不能只依赖 `chown`。
设置 `READER_TOKEN_SECRET` 只能省去密钥文件写入,不能替代数据库和缓存所需的写权限。
### 文件管理返回 `READ_ONLY_MOUNT`
检查卷是否为 `:ro`。改用 `:rw` 并重新创建容器后,还需确认服务进程对目标目录有写权限。上传仅在管理员文件管理页面提供。
### 页面打开但看不到书
确认挂载目录中的文件对服务进程可读,格式受支持,并等待扫描完成或由管理员手动扫描。扫描器跳过 `.git`、`@eaDir`、`#recycle` 等目录,不跟随符号链接;可在书库文件页核对实际目录。
### 远程书源搜索失败
+114
View File
@@ -0,0 +1,114 @@
# Development
[Project home](../README.en.md) · [Documentation](README.md) · [简体中文](development.zh-CN.md)
## Requirements
- Node.js 24 is recommended to match the current container and CI. The server uses built-in `node:sqlite`.
- npm and Git. Server, Web, and the source plugin have separate package manifests and lockfiles; there is no root-level npm script.
- Chromium for browser-rule tests and UI reviews.
- For Android: JDK 17+, Android SDK 35, and Build Tools 35.0.1. The Web asset script requires a POSIX shell; Windows users can use Git Bash or WSL.
Unless noted otherwise, run commands from the repository root.
## Install dependencies
## Start development servers
Open two terminals at the repository root. Use a test library and keep data outside it.
Linux/macOS:
```sh
mkdir -p /tmp/reader-dev-books /tmp/reader-dev-data
BOOKS_DIR=/tmp/reader-dev-books DATA_DIR=/tmp/reader-dev-data npm run dev --prefix server
```
PowerShell:
```powershell
$env:BOOKS_DIR = Join-Path $env:TEMP 'reader-dev-books'
$env:DATA_DIR = Join-Path $env:TEMP 'reader-dev-data'
New-Item -ItemType Directory -Force -Path $env:BOOKS_DIR, $env:DATA_DIR | Out-Null
npm run dev --prefix server
```
In the second terminal:
```sh
npm run dev --prefix web
```
Open `http://localhost:5174`. Vite proxies `/api` to `http://127.0.0.1:8080` by default. Set `READER_SERVER` to change the proxy target.
## Checks and tests
Run checks for the modules you change. Available entry points are:
```sh
npm run typecheck --prefix server
npm test --prefix server
npm run build --prefix server
npm run typecheck --prefix web
npm test --prefix web
npm run build --prefix web
Web tests use both Vitest and Node's test runner. Plugin tests include real Chromium; prepare it as described above. Historical test counts are not a substitute for current results.
For UI changes, run `npm run ui:review --prefix web`; source workflows have `npm run ui:sources --prefix web`. See [UI review (中文)](ui-review/README.md) for tooling and requirements. Reviews generate screenshots and reports; screenshots are ignored by Git by default.
## Build and run
### Single-container image
```sh
docker build -f server/Dockerfile -t reader:local .
```
Use the repository root as the build context. The image builds both the Web client and server. Set the Compose image to `reader:local`, or use its commented `build` configuration.
### Without a container
Build both server and Web with their `npm run build` scripts, then start from the repository root:
```sh
BOOKS_DIR=/tmp/reader-dev-books DATA_DIR=/tmp/reader-dev-data WEB_DIR="$PWD/web/dist" npm start --prefix server
```
In PowerShell, set `$env:BOOKS_DIR`, `$env:DATA_DIR`, and `$env:WEB_DIR = (Resolve-Path 'web/dist').Path`, then run `npm start --prefix server`. `WEB_DIR` must point to the built client; the server does not automatically locate another project's `web/dist` directory.
### Android
Build the shared Web assets from the repository root, then build the APK:
```sh
sh android/scripts/build-web-assets.sh
cd android
./gradlew :app:assembleDebug
```
Use `gradlew.bat` from a native Windows terminal. The output is `android/app/build/outputs/apk/debug/app-debug.apk`. Add `-PdefaultServerUrl=http://nas.local:8080` to preset the server address; otherwise users enter it and sign in. Building an APK does not validate reading on a physical device.
## Code map
| Directory | Responsibility |
| --- | --- |
| `server/src/config`, `db` | Runtime configuration, SQLite schema and access |
| `server/src/indexer` | File formats, scanning, identity, and metadata |
| `server/src/services`, `http` | Business services, API, authentication, and resources |
| `server/src/sources` | Built-in sources and generic plugin contracts |
| `web/src/formats` | EPUB, TXT, comics, and other format handling |
| `web/src/ui`, `styles` | Preact UI, reading stage, and styles |
| `web/src/core`, `store` | Platform capabilities, synchronization, and offline storage |
Preact manages UI state; the reading stage handles content layout and measurement. Shadow DOM isolates book styles, and icons use Lucide SVG. Both the server and Android consume the Web build. See [architecture (中文)](architecture.md) and [UI guidelines (中文)](ui.md) for details.
## Contributing workflow
1. Describe the issue, reproduction steps, and expected behavior. Remove credentials from logs, source rules, and examples.
2. Keep changes focused and follow existing error handling and test patterns.
3. Add appropriate regression checks for behavior changes. Documentation-only changes need link, command, and example checks.
4. Describe the changes, validation, and known limitations when submitting.
For integrations, see the [API reference (中文)](api.md), [source architecture (中文)](source-plugins.md), and [extension protocol (中文)](plugin-extensions.md).
+114
View File
@@ -0,0 +1,114 @@
# 开发指南
[项目首页](../README.md) · [文档中心](README.md) · [English](development.en.md)
## 环境
- 推荐 Node.js 24,与当前容器和 CI 保持一致;服务端使用内置 `node:sqlite`。
- npm、Git;服务端、Web 和书源插件各有独立 `package.json` 与锁文件,仓库根目录没有统一 npm 脚本。
- 运行浏览器规则测试或 UI 评审需要 Chromium。
- 构建 Android 另需 JDK 17+、Android SDK 35、Build Tools 35.0.1;Web 资源构建脚本需要 POSIX shell(Windows 可使用 Git Bash 或 WSL)。
以下命令从仓库根目录执行。
## 安装依赖
## 启动开发服务
在仓库根目录开两个终端。使用测试书库,不要把数据目录放进书库里。
Linux/macOS:
```sh
mkdir -p /tmp/reader-dev-books /tmp/reader-dev-data
BOOKS_DIR=/tmp/reader-dev-books DATA_DIR=/tmp/reader-dev-data npm run dev --prefix server
```
PowerShell:
```powershell
$env:BOOKS_DIR = Join-Path $env:TEMP 'reader-dev-books'
$env:DATA_DIR = Join-Path $env:TEMP 'reader-dev-data'
New-Item -ItemType Directory -Force -Path $env:BOOKS_DIR, $env:DATA_DIR | Out-Null
npm run dev --prefix server
```
第二个终端:
```sh
npm run dev --prefix web
```
访问 `http://localhost:5174`。Vite 默认把 `/api` 代理到 `http://127.0.0.1:8080`;通过 `READER_SERVER` 环境变量可调整代理目标。
## 检查与测试
按修改范围执行,以下是各模块入口:
```sh
npm run typecheck --prefix server
npm test --prefix server
npm run build --prefix server
npm run typecheck --prefix web
npm test --prefix web
npm run build --prefix web
Web 测试同时包含 Vitest 和 Node 测试。插件测试包含真实 Chromium;浏览器缺失时按上面的步骤准备环境。不要把历史测试数量当作当前验证结果。
UI 改动可运行 `npm run ui:review --prefix web`,书源流程可运行 `npm run ui:sources --prefix web`。评审工具及环境说明见 [UI 评审](ui-review/README.md),会生成截图和报告;截图目录默认不纳入 Git。
## 构建与运行
### 单容器镜像
```sh
docker build -f server/Dockerfile -t reader:local .
```
构建上下文必须是仓库根目录,镜像会同时构建 Web 和服务端。部署时将 Compose 的镜像名改为 `reader:local`,或使用文件内的 `build` 配置。
### 不使用容器
先执行两端的 `npm run build`,再从仓库根目录启动:
```sh
BOOKS_DIR=/tmp/reader-dev-books DATA_DIR=/tmp/reader-dev-data WEB_DIR="$PWD/web/dist" npm start --prefix server
```
PowerShell 中先设置 `$env:BOOKS_DIR`、`$env:DATA_DIR`,并将 `$env:WEB_DIR = (Resolve-Path 'web/dist').Path`,再运行 `npm start --prefix server`。`WEB_DIR` 需要指向产物目录,服务端不会自动猜测另一个项目中的 `web/dist`。
### Android
从仓库根目录构建 Web 资源,再构建 APK:
```sh
sh android/scripts/build-web-assets.sh
cd android
./gradlew :app:assembleDebug
```
Windows 原生终端使用 `gradlew.bat`。产物为 `android/app/build/outputs/apk/debug/app-debug.apk`。可通过 `-PdefaultServerUrl=http://nas.local:8080` 预设地址;未预设时由用户填写服务地址并登录。编译 APK 不等于完成真机阅读验证。
## 代码导览
| 目录 | 责任 |
| --- | --- |
| `server/src/config`、`db` | 运行时配置、SQLite schema 和访问层 |
| `server/src/indexer` | 文件格式、扫描、身份与元数据 |
| `server/src/services`、`http` | 业务服务、API、鉴权和资源交付 |
| `server/src/sources` | 内置来源和通用插件契约 |
| `web/src/formats` | EPUB、TXT、漫画等格式处理 |
| `web/src/ui`、`styles` | Preact 界面、阅读舞台和样式 |
| `web/src/core`、`store` | 平台能力、同步、离线存储 |
界面状态使用 Preact,阅读内容布局与测量由阅读舞台管理;书籍样式通过 Shadow DOM 隔离,图标使用 Lucide SVG。Web 产物由服务端和 Android 共同使用。详细取舍见[架构文档](architecture.md)和[界面规范](ui.md)。
## 贡献流程
1. 描述问题、复现步骤和期望行为;日志、书源及示例请移除凭据。
2. 将修改限制在相关模块,参考已有错误语义和测试方式。
3. 为行为变更补充适当的回归验证;纯文档修改检查链接、命令和示例即可。
4. 提交变更时说明改动、验证方式和已知限制。
API 详见 [API 文档](api.md),插件开发见[来源架构](source-plugins.md)与[扩展协议](plugin-extensions.md)。
+109
View File
@@ -0,0 +1,109 @@
# Getting started
[Project home](../README.en.md) · [Documentation](README.md) · [简体中文](getting-started.zh-CN.md)
This guide takes you through Docker deployment, account registration, and opening your first book. To run from source, use the [development guide](development.en.md).
## 1. Prepare your environment
- Install Docker Engine or Docker Desktop and the Docker Compose plugin.
- Prepare a book directory and a separate data directory.
- Make port `8080` available, or change the host port in Compose, for example to `8090:8080`.
The container serves both the API and Web UI. No separate frontend deployment is needed. Run the following commands from the repository root.
## 2. Get the deployment configuration
```sh
git clone https://cnb.cool/hectorqin/reader.git
cd reader
```
Edit [docker-compose.yml](../docker-compose.yml) and replace the host-side book path:
```yaml
volumes:
- /path/to/your/books:/books:ro
- ./data:/data
```
For example, use `/srv/books:/books:ro` on Linux, or `"D:/books:/books:ro"` with Docker Desktop on Windows. The relative `./data` path is resolved from the Compose file's directory.
| Directory | Purpose |
| --- | --- |
| `/books` (`BOOKS_DIR`) | Your existing book files |
| `/data` (`DATA_DIR`) | Database, accounts, reading records, covers, upload staging, downloaded files, and plugin data |
`DATA_DIR` must be outside `BOOKS_DIR` and must not be the same directory. Startup checks this constraint. Metadata stays in the data directory; reader does not create cover files or `.calibre` metadata beside your books.
### Choose read-only or writable books
- **Browse and read only**: keep `:ro`. Add books through the host or NAS and let reader scan them.
- **Manage files in the browser**: use `:rw` and give the server process write permission. Administrators can upload, rename, move, delete, and create directories in the library file manager.
A read-only book mount still allows shelves, progress, and notes to be saved in `/data`. See [configuration](configuration.en.md) for permissions and mount details.
## 3. Start and sign in
```sh
docker compose up -d
docker compose ps
docker compose logs --tail=100 reader
```
Open `http://localhost:8080`, or `http://<server-ip>:8080` from another device.
1. Register the first account. It automatically becomes the administrator.
2. Wait for the initial scan, then open a book from the shelf or library.
3. Create accounts for other members. Public registration is disabled by default after the first account.
To allow later self-registration, set `ALLOW_REGISTRATION: "true"` in the Compose `environment` section and run `docker compose up -d` again.
The health endpoint is `/api/v1/health`. For startup failures, missing books, or write errors, see [troubleshooting](configuration.en.md#troubleshooting).
### Without Compose
On Linux/macOS with a POSIX shell, you can also run the container using absolute mount paths:
```sh
mkdir -p ./data
docker run -d --name reader --restart unless-stopped \
-p 8080:8080 \
-v /path/to/your/books:/books:ro \
-v "$(pwd)/data:/data" \
cnb.cool/hectorqin/reader:latest
```
On Windows, the Compose setup above avoids shell-specific path and line-continuation syntax.
## 4. Add books and sources
### Local books
Place EPUB, TXT, PDF, CBZ/ZIP, or comic image directories in your mounted library. By default, the server runs scheduled scans every 30 minutes and checks for changes every 60 seconds. Administrators can trigger a scan manually. With a writable mount, uploads are available in the administrator file manager.
The shelf contains readable books; the library lets you browse the disk directory. Removing a book from a shelf is different from deleting its file. See the [user guide (中文)](user-guide.zh-CN.md).
### OPDS
As an administrator, add an OPDS source under Sources (书源) and configure its server URL. If authentication is required, set credentials for your current account. Open the source to browse or search its catalog and acquire books for your shelf.
## 5. Upgrade and back up
Back up both the book and data directories before upgrading. For a simple file-based SQLite backup, stop the service and copy the entire `/data` directory, including database auxiliary files, to avoid copying inconsistent live state.
```sh
docker compose stop
# Back up the host book directory and ./data here.
docker compose pull
docker compose up -d
```
Keep your data directory: it contains accounts, reading records, signing keys, and plugin state. Plugin packages are upgraded separately; disable the plugin in the UI before replacing its package.
## Next steps
- [User guide (中文)](user-guide.zh-CN.md): reading settings, shelves, sources, TTS, and offline access.
- [Configuration](configuration.en.md): environment variables, HTTPS, permissions, and troubleshooting.
- [Development](development.en.md): local setup, checks, Docker builds, and Android.
- [API reference (中文)](api.md): automation and integrations.
+109
View File
@@ -0,0 +1,109 @@
# 入门指南
[项目首页](../README.md) · [文档中心](README.md) · [English](getting-started.en.md)
本文带你完成 Docker 部署、注册账号和读取第一本书。直接从源码运行请看[开发指南](development.zh-CN.md)。
## 1. 准备环境
- 安装 Docker Engine 或 Docker Desktop,以及 Docker Compose 插件。
- 准备一个书籍目录和一个独立的数据目录。
- 确保主机的 `8080` 端口可用;也可修改 Compose 左侧端口,例如 `8090:8080`。
容器同时提供 API 和 Web 界面,无需单独部署前端。以下命令从仓库根目录执行。
## 2. 获取部署配置
```sh
git clone https://cnb.cool/hectorqin/reader.git
cd reader
```
编辑 [docker-compose.yml](../docker-compose.yml),把宿主机书籍路径替换为自己的路径:
```yaml
volumes:
- /path/to/your/books:/books:ro
- ./data:/data
```
例如 Linux 使用 `/srv/books:/books:ro`,Windows Docker Desktop 可使用 `"D:/books:/books:ro"`。相对路径 `./data` 位于 Compose 文件所在目录。
| 目录 | 用途 |
| --- | --- |
| `/books`(`BOOKS_DIR`) | 现有书籍文件 |
| `/data`(`DATA_DIR`) | 数据库、账号、阅读记录、封面缓存、上传暂存、下载文件和插件数据 |
`DATA_DIR` 不能与 `BOOKS_DIR` 相同,也不能位于其中;启动时会检查这项约束。元数据保存在数据目录,不会在书旁生成封面或 `.calibre` 文件。
### 选择只读或可写书库
- **只浏览和阅读**:保留 `:ro`。通过宿主机或 NAS 放入新书,等待扫描。
- **在网页管理文件**:改为 `:rw`,并确保服务进程对该目录有写权限。管理员可以在书库文件管理页上传、改名、移动、删除和新建目录。
只读书库不会妨碍进度、笔记或书架保存,这些数据写入 `/data`。挂载和权限的详细说明见[部署配置](configuration.zh-CN.md)。
## 3. 启动与首次登录
```sh
docker compose up -d
docker compose ps
docker compose logs --tail=100 reader
```
打开 `http://localhost:8080`;在另一台设备上使用 `http://<服务器IP>:8080`。
1. 注册第一个账号,该账号自动成为管理员。
2. 等待初次扫描,在书架或书库中打开一本书。
3. 为家人或其他成员创建账号。首个账号创建后默认关闭公开注册。
如需开放后续注册,在 Compose 的 `environment` 中设置 `ALLOW_REGISTRATION: "true"`,然后执行 `docker compose up -d`。
健康检查地址为 `/api/v1/health`。若启动失败、目录为空或无法写入,请看[故障排查](configuration.zh-CN.md#故障排查)。
### 不使用 Compose
在 Linux/macOS 的 POSIX shell 中,也可使用绝对路径启动容器:
```sh
mkdir -p ./data
docker run -d --name reader --restart unless-stopped \
-p 8080:8080 \
-v /path/to/your/books:/books:ro \
-v "$(pwd)/data:/data" \
cnb.cool/hectorqin/reader:latest
```
Windows 推荐使用上面的 Compose 配置,避免不同 shell 的路径和换行语法差异。
## 4. 添加书籍与来源
### 本地书籍
把 EPUB、TXT、PDF、CBZ/ZIP 或漫画图片目录放到挂载的书库中。默认每 30 分钟定时扫描,每 60 秒检查变化;管理员也可手动触发扫描。可写挂载下,上传入口位于管理员文件管理页。
书架显示可阅读的书籍;书库按磁盘目录浏览。从书架移除书籍与删除磁盘文件是两种不同操作。详见[使用手册](user-guide.zh-CN.md)。
### OPDS
管理员在「书源」添加 OPDS 来源并设置服务地址。需要认证时填写当前账号的来源凭据。打开来源后可浏览或搜索目录,获取书籍并加入书架。
## 5. 更新与备份
更新前备份书籍目录和数据目录。对 SQLite 采用简单文件备份时,先停止服务,再复制完整 `/data`(包括数据库及其辅助文件),避免复制运行中的不一致状态。
```sh
docker compose stop
# 在此备份宿主机上的书籍目录和 ./data
docker compose pull
docker compose up -d
```
不要删除数据目录:其中包含账号、阅读记录、签名密钥和插件状态。插件包需单独升级;替换包前先在界面停用插件。
## 下一步
- [使用手册](user-guide.zh-CN.md):阅读设置、书架、书源、朗读和离线。
- [部署配置](configuration.zh-CN.md):环境变量、HTTPS、目录权限和故障排查。
- [开发指南](development.zh-CN.md):本地运行、验证、构建镜像和 Android。
- [API 文档](api.md):自动化与集成。
+93
View File
@@ -0,0 +1,93 @@
# 使用手册
[项目首页](../README.md) · [文档中心](README.md) · [安装部署](getting-started.zh-CN.md)
本页介绍安装后的日常使用。部署参数见[配置指南](configuration.zh-CN.md),协议细节见 [API](api.md)。
## 书架与书库
- **书架**是当前账号的阅读列表,可搜索、排序、调整密度并查看阅读进度。
- **书库**按挂载目录浏览本地书籍,可将书加入书架。
- **文件管理**供管理员检查磁盘目录。挂载可写且目录权限允许时,可上传、改名、移动、删除和新建目录。
从书架移除只改变该账号的书架记录,不删除书文件。文件管理中的删除会修改磁盘,请按界面确认提示操作。书籍的改名或移动按已有身份更新路径,保留阅读记录。
上传 `.zip/.cbz` 时会作为合集解包,保留必要的目录层级。单纯想把 CBZ 作为书籍扫描时,也可以直接把文件放到宿主机书库目录。重名上传支持保留两份、跳过、覆盖或拒绝整批,具体错误语义见 [上传 API](api.md)。
## 支持格式
| 格式 | 日常使用 |
| --- | --- |
| EPUB | 保留出版方排版、内嵌字体、目录、脚注、竖排和振假名等内容 |
| TXT | 自动识别 UTF-8、GB18030、Big5、UTF-16,支持手动切换编码和章节推断 |
| CBZ / ZIP | 按自然顺序展示页面,支持漫画分页 |
| 图片目录 | 将符合条件的图片目录作为漫画书,支持卷结构 |
| PDF | 基础查看,不解析成可重排正文;功能取决于浏览器或设备查看器 |
`.rar/.cbr` 不支持;ZIP64、加密和分卷压缩包不支持。reader 不提供 EPUB、TXT、PDF 之间的通用转换。
## 扫描与元数据
默认每 30 分钟定时扫描、每 60 秒检查变化,管理员可以手动触发扫描。扫描先比较大小和修改时间,再按需计算内容哈希。`.git`、`@eaDir`、`#recycle` 等目录被跳过,符号链接不跟随。
图片目录会结合图片、卷目录和压缩包结构识别。目录中包含其他书籍文件时,不应将这些书吞并为一个漫画目录;目录识别和分页资源规则见[架构](architecture.md)及 [API](api.md)。
书籍身份与内容有关,不直接依赖文件路径。移动或重命名通常保留身份,相同内容副本会合并;修改文件内容可能改变识别结果。
手动元数据覆盖保存在数据库中,优先于书内信息和文件名解析,重新扫描不会覆盖手动值。撤销手动字段后回到提取值。当前没有内置在线元数据抓取服务;远程书源插件与本地书籍元数据处理是不同功能。
## 阅读设置
字号、主题和界面设置按设备保存;阅读进度和笔记随账号同步。
| 设置 | 作用 |
| --- | --- |
| 分页 / 滚动 | 按屏翻页或连续阅读 |
| 字号、行距、页边距、对齐 | 调整正文,部分设置可选择沿用原书 |
| 字体 | 在原字体栈之前加入选定字体 |
| 主题 | 白、米黄、浅绿、夜间 |
| 亮度 | 界面叠加调暗,不等同于修改设备系统亮度 |
| 图片适配 | 固定版式内容完整显示或适宽 |
| 翻页方向 | 漫画等固定版式内容支持左右方向切换 |
| TXT 编码 | 自动识别异常时手动选择 |
点击正文中央可切换工具栏,左右区域翻页;也可使用目录跳转章节。工具栏、目录和设置面板覆盖正文,避免显隐时重新挤压正文布局。电脑端支持方向键、PageUp/PageDown;Android 可通过外壳处理音量翻页。
EPUB 章节按需加载,长书的目录与传输窗口分开处理,跨窗口跳转会先取相应章节。图标为 Lucide SVG,界面布局与交互规范见 [UI 文档](ui.md)。
## 朗读
可使用三种语音来源:Android 系统 `TextToSpeech`、浏览器 `speechSynthesis`,或管理员配置的 HTTP 语音服务。
- 从当前位置或选区开始,按句朗读并高亮。
- 支持上一句、下一句、暂停、继续和停止。
- 可调整语速、选择可用语音;音调等选项由引擎能力决定。
- 可设置章末继续下一章或停止。
没有中文语音时,先检查设备安装的语音包和当前引擎。需要服务端语音时,参照 [HTTP 朗读配置](configuration.zh-CN.md#http-朗读)。
## OPDS 与远程书源
| Tab | 用途 |
| --- | --- |
| 书源管理 | 筛选、分组、启停和查看书源状态、最近错误 |
| 订阅管理 | 添加链接、设置定时更新、立即更新和暂停 |
| 导入书源 | 导入或编辑书源 JSON |
| 书源调试 | 对指定书源搜索,查看脱敏日志和解析结果 |
搜书与管理分开。按分组或指定书源搜索时,结果通过 Streamable HTTP 陆续合并显示;并发数可在实例设置中调整,搜索过程中可手动停止并保留已收到的结果。
阅读远程章节书时,可刷新目录、配置自动追更,也可在目录中选择其他书源并确认对应章节。换源保留书籍记录、书架和旧缓存;旧笔记、书签不会自动匹配到新源章节,请核对起始章节。
## 多用户与离线
首个账号是管理员,后续成员默认由管理员创建。每个账号的书架、进度、笔记和高亮独立。阅读界面参数属于当前设备,不随账号覆盖其他设备的设置。
离线时可使用已经缓存的内容,重新连通后同步阅读状态。远程章节当前以已读取章节缓存为主,不保证尚未读取的整本书可离线。停用或卸载插件后已有缓存可能仍可读,获取新内容需要恢复来源。整书预下载、缓存配额和自动淘汰尚未实现。
## 进一步阅读
- [配置与故障排查](configuration.zh-CN.md)
- [API:目录、资源、进度、上传和来源](api.md)
- [数据边界与实现决策](architecture.md)
- [书源插件扩展](plugin-extensions.md)