Introduce a provider-based notification system and wire it through the API and admin UI. Added INotificationProvider + notification service implementation and providers (apprise, discord, ntfy, pushover), plus a GET /api/admin/notifications/providers endpoint to expose provider metadata. Refactored code to use provider type strings (removed enum coupling), updated masking/encryption calls, and simplified the test notification endpoint to accept backendId or type+config and call sendToBackend directly. UI: NotificationsTab now fetches provider metadata and renders provider cards and dynamic config forms (fields driven by provider metadata). Added config field rendering, improved backend cards, and edit/delete actions. APIs: New providers route, updated admin notification CRUD routes to validate provider types dynamically, updated test route schema. Added download-client categories POST API to fetch categories from clients and wired postImportCategory handling in download-client routes. Other notable changes: BookDate now fetches Claude models dynamically from Anthropic's Models API; added paginated model fetch helper. Added ALLOW_WEAK_PASSWORD flag exposure to auth providers and password change logic. Doc updates and various tests added/updated. File-organization doc clarifies EPERM fix using stream-based copy.
ReadMeABook - Unified Container Deployment
This guide covers deploying ReadMeABook using the unified container image that bundles PostgreSQL, Redis, and the application into a single container.
🚀 Quick Start
Option 1: Docker Compose (Recommended)
-
Download the compose file:
curl -O https://raw.githubusercontent.com/kikootwo/ReadMeABook/main/docker-compose.unified.yml -
Create required directories:
mkdir -p config downloads media -
Start the container:
docker compose -f docker-compose.unified.yml up -d -
Access the application: Open http://localhost:3030 in your browser
Option 2: Docker Run
# Create directories
mkdir -p config downloads media
# Run container
docker run -d \
--name readmeabook \
-p 3030:3030 \
-v ./config:/app/config \
-v ./downloads:/downloads \
-v ./media:/media \
-v readmeabook-data:/var/lib/postgresql/data \
-v readmeabook-redis:/var/lib/redis \
ghcr.io/kikootwo/readmeabook:latest
📋 Environment Variables
Most environment variables are optional with secure defaults generated automatically. Only configure these if needed:
Security (Auto-generated if not set)
JWT_SECRET- JWT token signing secretJWT_REFRESH_SECRET- Refresh token signing secretCONFIG_ENCRYPTION_KEY- Database encryption keyPOSTGRES_PASSWORD- PostgreSQL password
Application (Optional)
PUBLIC_URL- Your public URL (e.g.,https://readmeabook.example.com)LOG_LEVEL- Logging level:debug,info,warn,error(default:info)PLEX_CLIENT_IDENTIFIER- Custom Plex client ID (auto-generated if not set)
Database (Optional)
POSTGRES_USER- Database user (default:readmeabook)POSTGRES_DB- Database name (default:readmeabook)
📁 Volume Mounts
| Path | Description | Required |
|---|---|---|
/app/config |
Application configuration and logs | Yes |
/downloads |
Torrent download directory | Yes |
/media |
Plex audiobook library | Yes |
/var/lib/postgresql/data |
PostgreSQL data (persistent) | Yes |
/var/lib/redis |
Redis data (persistent) | Yes |
🔍 Viewing Logs
The unified container outputs logs from all services (PostgreSQL, Redis, and the app):
# View all logs
docker logs readmeabook-unified
# Follow logs in real-time
docker logs -f readmeabook-unified
# Filter by service
docker logs readmeabook-unified 2>&1 | grep "postgresql"
docker logs readmeabook-unified 2>&1 | grep "redis"
docker logs readmeabook-unified 2>&1 | grep "app"
🔧 Advanced Configuration
Custom Secrets
For production deployments, set custom secrets:
# docker-compose.unified.yml
environment:
JWT_SECRET: "your-secure-random-string-here"
JWT_REFRESH_SECRET: "another-secure-random-string"
CONFIG_ENCRYPTION_KEY: "32-character-encryption-key"
POSTGRES_PASSWORD: "secure-database-password"
Generate secure secrets:
openssl rand -base64 32
Reverse Proxy Setup
Example Nginx configuration:
server {
listen 80;
server_name readmeabook.example.com;
location / {
proxy_pass http://localhost:3030;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
Don't forget to set PUBLIC_URL environment variable:
environment:
PUBLIC_URL: "https://readmeabook.example.com"
🔄 Updating
# Pull latest image
docker compose -f docker-compose.unified.yml pull
# Restart with new image
docker compose -f docker-compose.unified.yml up -d
# View logs to ensure smooth startup
docker compose -f docker-compose.unified.yml logs -f
Database migrations run automatically on startup.
🐛 Troubleshooting
Container won't start
# Check logs for errors
docker logs readmeabook-unified
# Check container status
docker ps -a | grep readmeabook
Database issues
# Access PostgreSQL directly
docker exec -it readmeabook-unified su - postgres -c "psql -h 127.0.0.1 -U readmeabook"
# Check database status
docker exec readmeabook-unified su - postgres -c "pg_isready -h 127.0.0.1"
Redis issues
# Test Redis connection
docker exec readmeabook-unified redis-cli ping
# Should return: PONG
Reset everything
# Stop and remove container
docker compose -f docker-compose.unified.yml down
# Remove volumes (WARNING: deletes all data)
docker volume rm readmeabook-pgdata readmeabook-redis
# Start fresh
docker compose -f docker-compose.unified.yml up -d
📊 Resource Usage
The unified container typically uses:
- Memory: ~500MB-1GB (depending on usage)
- CPU: Low (spikes during library scans and downloads)
- Disk: Varies based on database size and Redis cache
🔐 Security Notes
- Change default secrets in production (set environment variables)
- Use HTTPS via reverse proxy (Nginx, Caddy, Traefik)
- Restrict port access - only expose 3030 to trusted networks
- Keep container updated - pull latest images regularly
- Backup data - regularly backup the PostgreSQL volume
📦 Backup & Restore
Backup Database
docker exec readmeabook-unified su - postgres -c \
"pg_dump -h 127.0.0.1 -U readmeabook readmeabook" > backup.sql
Restore Database
cat backup.sql | docker exec -i readmeabook-unified su - postgres -c \
"psql -h 127.0.0.1 -U readmeabook readmeabook"
🆚 Unified vs Multi-Container
Use Unified Container When:
- ✅ Simple deployment with minimal configuration
- ✅ Single-host deployment
- ✅ Don't need separate database/cache scaling
- ✅ Want easy updates and management
Use Multi-Container When:
- ✅ Need to scale services independently
- ✅ Want separate database backups
- ✅ Running in Kubernetes or orchestrated environment
- ✅ Need external access to database/Redis
📚 More Information
- Full Documentation: documentation/
- Multi-Container Setup: docker-compose.yml
- Issues: GitHub Issues
- Contributing: CONTRIBUTING.md
⚖️ License
MIT License - see LICENSE for details