Backup & Recovery - digitalunconciousness/shiftledger GitHub Wiki
Backup & Recovery
ShiftLedger uses a single SQLite database file (shifts.db), making backups simple — it's just a file copy.
Automated Backups
The installer sets up a daily cron job that runs at 3:00 AM:
0 3 * * * /opt/shiftledger/backup.sh /opt/shiftledger/shifts.db /opt/shiftledger/backups
What the Backup Script Does
- Copies
shifts.dbtobackups/shifts-YYYYMMDD-HHMMSS.db - Prunes backups older than 30 days
- Logs the backup file path and size
Verify Cron is Set Up
crontab -l | grep shiftledger
Check Existing Backups
ls -lh /opt/shiftledger/backups/
Manual Backup
Run the backup script directly at any time:
/opt/shiftledger/backup.sh
Or with custom paths:
/opt/shiftledger/backup.sh /opt/shiftledger/shifts.db /path/to/custom/backup/dir
Quick One-Liner
cp /opt/shiftledger/shifts.db /opt/shiftledger/shifts-$(date +%Y%m%d).db
Off-Site Backup
For added safety, copy backups to another machine:
# rsync to another server
rsync -av /opt/shiftledger/backups/ user@backup-server:/backups/shiftledger/
# Or use scp
scp /opt/shiftledger/backups/latest.db user@backup-server:/backups/
Consider adding an rsync command to the cron job or running a separate cron for off-site copies.
Restoring from Backup
1. Stop the Service
sudo systemctl stop shiftledger
2. Replace the Database
# Move the current (possibly corrupted) database aside
mv /opt/shiftledger/shifts.db /opt/shiftledger/shifts.db.broken
# Copy the backup in
cp /opt/shiftledger/backups/shifts-20260310-030001.db /opt/shiftledger/shifts.db
# Fix ownership
chown shiftledger:shiftledger /opt/shiftledger/shifts.db
3. Clean Up WAL Files
SQLite WAL (Write-Ahead Log) files should be removed when restoring:
rm -f /opt/shiftledger/shifts.db-wal /opt/shiftledger/shifts.db-shm
4. Restart
sudo systemctl start shiftledger
Migrations will run automatically if the backup is from an older version.
Verifying a Backup
You can inspect any backup without affecting the live database:
# Check integrity
sqlite3 /opt/shiftledger/backups/shifts-20260310-030001.db "PRAGMA integrity_check;"
# Count records
sqlite3 /opt/shiftledger/backups/shifts-20260310-030001.db "SELECT COUNT(*) FROM shifts WHERE deleted_at IS NULL;"
# Check schema version
sqlite3 /opt/shiftledger/backups/shifts-20260310-030001.db "SELECT value FROM meta WHERE key = 'db_version';"
Retention Policy
The default backup script retains backups for 30 days. To change this, edit backup.sh and modify the RETENTION_DAYS variable:
RETENTION_DAYS=30 # change to your preferred number
Disaster Recovery Checklist
If the server is completely lost and you have a backup of shifts.db:
- Set up a new server following the Deployment Guide
- Run the installer
- Stop the service:
sudo systemctl stop shiftledger - Replace the empty database with your backup:
cp backup.db /opt/shiftledger/shifts.db - Fix ownership:
chown shiftledger:shiftledger /opt/shiftledger/shifts.db - Start the service:
sudo systemctl start shiftledger - All data, users, and sessions will be restored (users may need to log in again if the
SESSION_SECRETchanged)