Claude-skill-registry litestream-coder
This skill guides configuring Litestream for continuous SQLite backup in Rails 8+ apps. Use when setting up production backups for SQLite databases (Solid Queue, Solid Cache, Solid Cable).
install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/litestream-coder" ~/.claude/skills/majiayu000-claude-skill-registry-litestream-coder && rm -rf "$T"
manifest:
skills/data/litestream-coder/SKILL.mdsource content
Litestream Coder
Overview
Litestream provides continuous streaming backup for SQLite databases to S3-compatible storage. Essential for Rails 8+ apps using SQLite in production with Solid Queue, Solid Cache, and Solid Cable.
Configuration File
Create
config/litestream.yml:
dbs: - path: /rails/storage/production.sqlite3 replicas: - type: s3 bucket: ${BUCKET_NAME} path: sqlite/production endpoint: ${S3_ENDPOINT} region: ${S3_REGION} access-key-id: ${LITESTREAM_ACCESS_KEY_ID} secret-access-key: ${LITESTREAM_SECRET_ACCESS_KEY} force-path-style: true # Required for S3-compatible storage sync-interval: 5s # How often to sync WAL snapshot-interval: 1h # Full snapshot frequency retention: 168h # 7 days retention-check-interval: 1h validation-interval: 12h
Retention Strategies by Database Type
Primary database (production.sqlite3):
- Frequent syncing for data durabilitysync-interval: 5s
- Hourly snapshotssnapshot-interval: 1h
- 30 days for recoveryretention: 720h
Cache database (production_cache.sqlite3):
- Less critical, reduce loadsync-interval: 10s
- Less frequentsnapshot-interval: 6h
- 1 day sufficientretention: 24h
Queue database (production_queue.sqlite3):
- Important for job durabilitysync-interval: 5s
- Hourlysnapshot-interval: 1h
- 3 days for debuggingretention: 72h
Cable database (production_cable.sqlite3):
- Ephemeral datasync-interval: 10s
- Infrequentsnapshot-interval: 6h
- 1 dayretention: 24h
Complete Configuration Example
dbs: - path: /rails/storage/production.sqlite3 replicas: - type: s3 bucket: myapp-backups path: sqlite/production endpoint: https://fsn1.your-objectstorage.com region: fsn1 access-key-id: ${LITESTREAM_ACCESS_KEY_ID} secret-access-key: ${LITESTREAM_SECRET_ACCESS_KEY} force-path-style: true sync-interval: 5s snapshot-interval: 1h retention: 720h retention-check-interval: 1h validation-interval: 12h - path: /rails/storage/production_cache.sqlite3 replicas: - type: s3 bucket: myapp-backups path: sqlite/cache endpoint: https://fsn1.your-objectstorage.com region: fsn1 access-key-id: ${LITESTREAM_ACCESS_KEY_ID} secret-access-key: ${LITESTREAM_SECRET_ACCESS_KEY} force-path-style: true sync-interval: 10s snapshot-interval: 6h retention: 24h - path: /rails/storage/production_queue.sqlite3 replicas: - type: s3 bucket: myapp-backups path: sqlite/queue endpoint: https://fsn1.your-objectstorage.com region: fsn1 access-key-id: ${LITESTREAM_ACCESS_KEY_ID} secret-access-key: ${LITESTREAM_SECRET_ACCESS_KEY} force-path-style: true sync-interval: 5s snapshot-interval: 1h retention: 72h - path: /rails/storage/production_cable.sqlite3 replicas: - type: s3 bucket: myapp-backups path: sqlite/cable endpoint: https://fsn1.your-objectstorage.com region: fsn1 access-key-id: ${LITESTREAM_ACCESS_KEY_ID} secret-access-key: ${LITESTREAM_SECRET_ACCESS_KEY} force-path-style: true sync-interval: 10s snapshot-interval: 6h retention: 24h
Kamal 2 Deployment
Add Litestream as an accessory in
config/deploy.yml:
accessories: litestream: image: litestream/litestream:0.3 host: <SERVER_IP> cmd: replicate volumes: - "myapp_storage:/rails/storage:ro" # Read-only access files: - config/litestream.yml:/etc/litestream.yml env: secret: - LITESTREAM_ACCESS_KEY_ID - LITESTREAM_SECRET_ACCESS_KEY options: health-cmd: "litestream databases || exit 1" health-interval: 30s health-timeout: 5s health-retries: 3
Key points:
- Mount storage as read-only (
) - Litestream only reads WAL files:ro - Use same volume name as main app
- Health check verifies Litestream can see databases
Secrets Configuration
In
.kamal/secrets:
LITESTREAM_ACCESS_KEY_ID=$(op read "op://myproject/production-s3/access_key_id") LITESTREAM_SECRET_ACCESS_KEY=$(op read "op://myproject/production-s3/secret_access_key")
Disaster Recovery
Restore Database
# Stop application first kamal app stop # Restore from latest backup docker run --rm \ -v myapp_storage:/rails/storage \ -e LITESTREAM_ACCESS_KEY_ID="$(op read 'op://myproject/production-s3/access_key_id')" \ -e LITESTREAM_SECRET_ACCESS_KEY="$(op read 'op://myproject/production-s3/secret_access_key')" \ litestream/litestream:0.3 restore \ -config /etc/litestream.yml \ /rails/storage/production.sqlite3 # Restart application kamal app start
Point-in-Time Recovery
docker run --rm \ -v myapp_storage:/rails/storage \ -e LITESTREAM_ACCESS_KEY_ID="..." \ -e LITESTREAM_SECRET_ACCESS_KEY="..." \ litestream/litestream:0.3 restore \ -config /etc/litestream.yml \ -timestamp "2025-01-15T10:30:00Z" \ /rails/storage/production.sqlite3
Monitoring
Check backup status:
# Via Kamal kamal accessory exec litestream -- litestream databases # Direct on server docker exec myapp-litestream litestream databases
S3-Compatible Storage
Litestream works with any S3-compatible storage:
| Provider | Endpoint Example |
|---|---|
| Hetzner Object Storage | |
| Backblaze B2 | |
| DigitalOcean Spaces | |
| AWS S3 | (omit endpoint, use region) |
Critical: Always set
force-path-style: true for non-AWS S3-compatible storage.
Best Practices
- Separate databases by retention needs - Main DB needs longer retention than cache
- Monitor backup lag -
shows replication statuslitestream databases - Test restores regularly - Don't wait for a disaster to verify backups work
- Use read-only mount - Litestream only reads WAL files,
prevents accidents:ro