55
66A simple Python/FastAPI server for syncing reading progress across KOReader devices.
77
8- ## Running Sync Server
8+ ## Quick Start (Hosted Server)
9+
10+ Don't want to deploy your own? Use the public sync server:
11+
12+ ** ` https://null-space.xyz/reader ` **
13+
14+ Just point your KOReader or Readest app to this URL and create an account.
15+
16+ ## Running Sync Server (Self-Hosted)
917
1018### Local Development
1119
@@ -22,12 +30,69 @@ uvicorn main:app --reload --port 8080
2230docker compose up -d
2331```
2432
33+ ### AWS Lambda
34+
35+ Deploy as a serverless Lambda function with DynamoDB storage.
36+
37+ #### Prerequisites
38+
39+ - AWS CLI configured with credentials
40+ - Terraform >= 1.0
41+ - Python 3.12
42+
43+ #### One-Time Bootstrap
44+
45+ Create the shared S3 bucket for Terraform state:
46+
47+ ``` bash
48+ cd deployment
49+ ./bootstrap.sh
50+ ```
51+
52+ #### Deploy
53+
54+ 1 . Create terraform variables file:
55+
56+ ``` bash
57+ cp deployment/terraform.tfvars.example terraform/terraform.tfvars
58+ ```
59+
60+ 2 . Edit ` terraform/terraform.tfvars ` with your password salt:
61+
62+ ``` hcl
63+ password_salt = "your-secure-random-salt" # Generate with: openssl rand -hex 32
64+ ```
65+
66+ 3 . Build and deploy:
67+
68+ ``` bash
69+ ./deployment/deploy.sh
70+ ```
71+
72+ This creates:
73+ - Lambda function (` reader-progress-prod ` )
74+ - DynamoDB tables (` reader-progress-prod-users ` , ` reader-progress-prod-progress ` )
75+ - IAM role with minimal permissions
76+
2577## Configuration
2678
79+ ### Docker / Local Development
80+
2781| Environment Variable | Default | Description |
2882| ---------------------| ---------| -------------|
29- | PASSWORD_SALT | ` default-salt-change-me ` | Salt prepended to passwords before hashing |
30- | DATABASE_URL | ` sqlite:///./data/koreader.db ` | SQLite database path |
83+ | ` DB_BACKEND ` | ` sql ` | Database backend (` sql ` or ` dynamodb ` ) |
84+ | ` PASSWORD_SALT ` | ` default-salt-change-me ` | Salt prepended to passwords before hashing |
85+ | ` DATABASE_URL ` | ` sqlite:///./data/koreader.db ` | SQLite/PostgreSQL database URL |
86+
87+ ### AWS Lambda
88+
89+ | Environment Variable | Description |
90+ | ---------------------| -------------|
91+ | ` DB_BACKEND ` | Set to ` dynamodb ` |
92+ | ` PASSWORD_SALT ` | Salt for password hashing (set via Terraform) |
93+ | ` DYNAMODB_USERS_TABLE ` | Users table name (set via Terraform) |
94+ | ` DYNAMODB_PROGRESS_TABLE ` | Progress table name (set via Terraform) |
95+ | ` AWS_REGION ` | AWS region (set via Terraform) |
3196
3297## KOReader Setup
3398
@@ -77,15 +142,17 @@ The document hash ensures the same book is identified across devices regardless
77142
78143## Database Structure
79144
80- ### Users Table
145+ ### SQLite/PostgreSQL (Docker/Local)
146+
147+ #### Users Table
81148
82149| Column | Type | Description |
83150| --------| ------| -------------|
84151| id | INTEGER | Primary key |
85152| username | TEXT | Unique username |
86153| password_hash | TEXT | Bcrypt hash of salted MD5 password |
87154
88- ### Progress Table
155+ #### Progress Table
89156
90157| Column | Type | Description |
91158| --------| ------| -------------|
@@ -100,6 +167,27 @@ The document hash ensures the same book is identified across devices regardless
100167
101168** Key constraint** : One progress record per (user_id, document) pair. Updates replace existing records.
102169
170+ ### DynamoDB (AWS Lambda)
171+
172+ #### Users Table
173+
174+ | Attribute | Type | Key |
175+ | -----------| ------| -----|
176+ | username | String | Partition Key |
177+ | password_hash | String | - |
178+
179+ #### Progress Table
180+
181+ | Attribute | Type | Key |
182+ | -----------| ------| -----|
183+ | user_id | String | Partition Key |
184+ | document | String | Sort Key |
185+ | progress | String | - |
186+ | percentage | Number | - |
187+ | device | String | - |
188+ | device_id | String | - |
189+ | timestamp | Number | - |
190+
103191## API Reference
104192
105193### Authentication
0 commit comments