mirror of
https://github.com/readur/readur.git
synced 2025-12-30 19:10:22 -06:00
9.0 KiB
9.0 KiB
Deployment Guide
This guide covers production deployment strategies, SSL setup, monitoring, backups, and best practices for running Readur in production.
Table of Contents
- Production Docker Compose
- Network Filesystem Mounts
- SSL/HTTPS Setup
- Health Checks
- Backup Strategy
- Monitoring
- Deployment Platforms
- Security Considerations
Production Docker Compose
For production deployments, create a custom docker-compose.prod.yml:
services:
readur:
image: readur:latest
ports:
- "8000:8000"
environment:
# Core Configuration
- DATABASE_URL=postgresql://readur:${DB_PASSWORD}@postgres:5432/readur
- JWT_SECRET=${JWT_SECRET}
- SERVER_ADDRESS=0.0.0.0:8000
# File Storage
- UPLOAD_PATH=/app/uploads
- WATCH_FOLDER=/app/watch
- ALLOWED_FILE_TYPES=pdf,png,jpg,jpeg,tiff,bmp,gif,txt,doc,docx
# Watch Folder Settings
- WATCH_INTERVAL_SECONDS=30
- FILE_STABILITY_CHECK_MS=500
- MAX_FILE_AGE_HOURS=168
# OCR Configuration
- OCR_LANGUAGE=eng
- CONCURRENT_OCR_JOBS=4
- OCR_TIMEOUT_SECONDS=300
- MAX_FILE_SIZE_MB=100
# Performance Tuning
- MEMORY_LIMIT_MB=1024
- CPU_PRIORITY=normal
- ENABLE_COMPRESSION=true
volumes:
# Document storage
- ./data/uploads:/app/uploads
# Watch folder - mount your network drives here
- /mnt/nfs/documents:/app/watch
# or SMB: - /mnt/smb/shared:/app/watch
# or S3: - /mnt/s3/bucket:/app/watch
depends_on:
- postgres
restart: unless-stopped
# Resource limits for production
deploy:
resources:
limits:
memory: 2G
cpus: '2.0'
reservations:
memory: 512M
cpus: '0.5'
postgres:
image: postgres:15
environment:
- POSTGRES_USER=readur
- POSTGRES_PASSWORD=${DB_PASSWORD}
- POSTGRES_DB=readur
- POSTGRES_INITDB_ARGS=--encoding=UTF-8 --lc-collate=en_US.UTF-8 --lc-ctype=en_US.UTF-8
volumes:
- postgres_data:/var/lib/postgresql/data
- ./postgres-config:/etc/postgresql/conf.d:ro
# PostgreSQL optimization for document search
command: >
postgres
-c shared_buffers=256MB
-c effective_cache_size=1GB
-c max_connections=100
-c default_text_search_config=pg_catalog.english
restart: unless-stopped
# Don't expose port in production
# ports:
# - "5433:5432"
volumes:
postgres_data:
driver: local
Deploy with environment file:
# Create .env file with secrets
cat > .env << EOF
JWT_SECRET=$(openssl rand -base64 64)
DB_PASSWORD=$(openssl rand -base64 32)
EOF
# Deploy
docker compose -f docker-compose.prod.yml --env-file .env up -d
Network Filesystem Mounts
NFS Mounts
# Mount NFS share
sudo mount -t nfs 192.168.1.100:/documents /mnt/nfs/documents
# Add to docker-compose.yml
volumes:
- /mnt/nfs/documents:/app/watch
environment:
- WATCH_INTERVAL_SECONDS=60
- FILE_STABILITY_CHECK_MS=1000
- FORCE_POLLING_WATCH=1
SMB/CIFS Mounts
# Mount SMB share
sudo mount -t cifs //server/share /mnt/smb/shared -o username=user,password=pass
# Docker volume configuration
volumes:
- /mnt/smb/shared:/app/watch
environment:
- WATCH_INTERVAL_SECONDS=30
- FILE_STABILITY_CHECK_MS=2000
S3 Mounts
# Mount S3 bucket using s3fs
s3fs mybucket /mnt/s3/bucket -o passwd_file=~/.passwd-s3fs
# Docker configuration for S3
volumes:
- /mnt/s3/bucket:/app/watch
environment:
- WATCH_INTERVAL_SECONDS=120
- FILE_STABILITY_CHECK_MS=5000
- FORCE_POLLING_WATCH=1
SSL/HTTPS Setup
Nginx Configuration
server {
listen 443 ssl http2;
server_name readur.yourdomain.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
location / {
proxy_pass http://localhost:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# For file uploads
client_max_body_size 100M;
proxy_read_timeout 300s;
proxy_send_timeout 300s;
}
}
Traefik Configuration
services:
readur:
labels:
- "traefik.enable=true"
- "traefik.http.routers.readur.rule=Host(`readur.yourdomain.com`)"
- "traefik.http.routers.readur.tls=true"
- "traefik.http.routers.readur.tls.certresolver=letsencrypt"
📘 For more reverse proxy configurations including Apache, Caddy, custom ports, load balancing, and advanced scenarios, see REVERSE_PROXY.md.
Health Checks
Add health checks to your Docker configuration:
services:
readur:
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/api/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
Backup Strategy
Create an automated backup script:
#!/bin/bash
# backup.sh - Automated backup script
BACKUP_DIR="/path/to/backups"
DATE=$(date +%Y%m%d_%H%M%S)
# Create backup directory
mkdir -p "$BACKUP_DIR"
# Backup database
docker exec readur-postgres-1 pg_dump -U readur readur | gzip > "$BACKUP_DIR/db_backup_$DATE.sql.gz"
# Backup uploaded files
tar -czf "$BACKUP_DIR/uploads_backup_$DATE.tar.gz" -C ./data uploads/
# Clean old backups (keep 30 days)
find "$BACKUP_DIR" -name "db_backup_*.sql.gz" -mtime +30 -delete
find "$BACKUP_DIR" -name "uploads_backup_*.tar.gz" -mtime +30 -delete
echo "Backup completed: $DATE"
Add to crontab for daily backups:
0 2 * * * /path/to/backup.sh >> /var/log/readur-backup.log 2>&1
Restore from Backup
# Restore database
gunzip -c db_backup_20240101_020000.sql.gz | docker exec -i readur-postgres-1 psql -U readur readur
# Restore files
tar -xzf uploads_backup_20240101_020000.tar.gz -C ./data
Monitoring
Monitor your deployment with Docker stats:
# Real-time resource usage
docker stats
# Container logs
docker compose logs -f readur
# Watch folder activity
docker compose logs -f readur | grep watcher
# PostgreSQL query performance
docker exec readur-postgres-1 psql -U readur -c "SELECT * FROM pg_stat_statements ORDER BY total_time DESC LIMIT 10;"
Prometheus Metrics
Readur exposes metrics at /metrics endpoint:
# prometheus.yml
scrape_configs:
- job_name: 'readur'
static_configs:
- targets: ['readur:8000']
Deployment Platforms
Docker Swarm
version: '3.8'
services:
readur:
image: readur:latest
deploy:
replicas: 2
restart_policy:
condition: on-failure
placement:
constraints: [node.role == worker]
networks:
- readur-network
secrets:
- jwt_secret
- db_password
secrets:
jwt_secret:
external: true
db_password:
external: true
Kubernetes
apiVersion: apps/v1
kind: Deployment
metadata:
name: readur
spec:
replicas: 3
selector:
matchLabels:
app: readur
template:
spec:
containers:
- name: readur
image: readur:latest
env:
- name: JWT_SECRET
valueFrom:
secretKeyRef:
name: readur-secrets
key: jwt-secret
resources:
limits:
memory: "2Gi"
cpu: "2"
requests:
memory: "512Mi"
cpu: "500m"
Cloud Platforms
- AWS: Use ECS with RDS PostgreSQL
- Google Cloud: Deploy to Cloud Run with Cloud SQL
- Azure: Use Container Instances with Azure Database
- DigitalOcean: App Platform with Managed Database
Security Considerations
Production Checklist
- Change default admin password
- Generate strong JWT secret
- Use HTTPS/SSL in production
- Restrict database network access
- Set proper file permissions
- Enable firewall rules
- Regular security updates
- Monitor access logs
- Implement rate limiting
- Enable audit logging
Recommended Production Setup
# Generate secure secrets
JWT_SECRET=$(openssl rand -base64 64)
DB_PASSWORD=$(openssl rand -base64 32)
# Restrict file permissions
chmod 600 .env
chmod 700 ./data/uploads
# Use read-only root filesystem
docker run --read-only --tmpfs /tmp ...
Next Steps
- Configure monitoring and alerting
- Review security best practices
- Set up automated backups
- Explore database guardrails