Backups & Restoration
Overview
Tududi automatically creates SQLite database file backups before migrations and on startup to protect your data. These backups ensure you have a recovery point if a migration fails or if you need to restore to a previous state.
Automatic SQLite File Backups
When Backups Are Created
SQLite database file backups are automatically created in these scenarios:
- Before migrations - Every time the app starts and finds an existing database
- On startup - Before running any database operations (Docker/production)
- Manual trigger - Via the backup script
Location: /backend/cmd/start.sh (lines 9-78)
Backup File Location
- Development:
/backend/db/db-backup-YYYYMMDDHHMMSS.sqlite3 - Docker/Production:
/app/backend/db/db-backup-YYYYMMDDHHMMSS.sqlite3(mounted volume)
Backup Retention Policy
The system automatically manages backup retention with these rules:
| Timeframe | Retention Policy |
|---|---|
| Today | Keep up to 4 most recent backups |
| Past 7 days | Keep 1 backup per day (most recent) |
| Older than 7 days | Automatically deleted |
Example:
db-backup-20260315083000.sqlite3 ← Today (backup #1)
db-backup-20260315070000.sqlite3 ← Today (backup #2)
db-backup-20260314193000.sqlite3 ← Yesterday (only 1 kept)
db-backup-20260313100000.sqlite3 ← 2 days ago (only 1 kept)
db-backup-20260308120000.sqlite3 ← Automatically deleted (>7 days)
How Automatic Backups Work
When the app starts (via npm start or Docker):
- Check if
DB_FILEexists - If exists, call
backup_db()function - Clean old backups based on retention policy
- Create timestamped copy:
cp $DB_FILE $backup_file - Run migrations:
npx sequelize-cli db:migrate - Start application
Critical: Backups are created before migrations run, ensuring you have a recovery point if a migration fails.
Restoring from SQLite File Backup
Quick Restore (Development)
# 1. Stop the application
npm stop # or Ctrl+C
# 2. List available backups
ls -lh backend/db/db-backup-*.sqlite3
# 3. Identify the backup to restore (e.g., db-backup-20260314193000.sqlite3)
# 4. Backup current state (optional but recommended)
cp backend/db/development.sqlite3 backend/db/development.sqlite3.before-restore
# 5. Restore the backup
cp backend/db/db-backup-20260314193000.sqlite3 backend/db/development.sqlite3
# 6. Restart the application
npm start
Restore in Docker
# 1. Stop the container
docker-compose down
# 2. Access the host volume (find your volume location)
docker volume inspect tududi_db_data
# 3. Navigate to the mount point and list backups
cd /var/lib/docker/volumes/tududi_db_data/_data
ls -lh db-backup-*.sqlite3
# 4. Backup current state
cp production.sqlite3 production.sqlite3.before-restore
# 5. Restore from backup
cp db-backup-20260314193000.sqlite3 production.sqlite3
# 6. Restart the container
docker-compose up -d
Emergency Restore (Production)
If a migration fails and the app won't start:
# The start script creates a backup BEFORE migrations
# So the most recent backup is from before the failed migration
cd backend/db
# Find the most recent backup (will be from just before failure)
ls -lt db-backup-*.sqlite3 | head -1
# Restore it
cp db-backup-20260315083000.sqlite3 production.sqlite3
# Try starting again
npm start
Best Practices
1. Before Major Changes
Create a manual backup before:
- Upgrading Tududi to a new version
- Running manual migrations
- Bulk data operations
- Testing new features
# Quick manual backup (development)
cp backend/db/development.sqlite3 backend/db/manual-backup-$(date +%Y%m%d%H%M%S).sqlite3
2. External Backups
For production:
- Copy
/backend/db/*.sqlite3to external storage weekly - Test restore procedures periodically
3. Docker Volume Backups
Backup the entire Docker volume:
# Backup Docker volume
docker run --rm \
-v tududi_db_data:/data \
-v $(pwd):/backup \
alpine tar czf /backup/tududi-db-backup-$(date +%Y%m%d).tar.gz -C /data .
# Restore Docker volume
docker run --rm \
-v tududi_db_data:/data \
-v $(pwd):/backup \
alpine tar xzf /backup/tududi-db-backup-20260314.tar.gz -C /data
4. Migration Rollback Strategy
If a migration fails:
- Don't panic - automatic backup was created
- Stop the application
- Restore the most recent automatic backup (created before migration)
- Investigate the migration issue
- Fix the migration or rollback:
npm run migration:undo
5. Test Restore Procedures
Periodically test that backups can be restored:
# Test restore in a safe environment
cp backend/db/db-backup-20260314193000.sqlite3 backend/db/test-restore.sqlite3
# Verify the backup file is readable
sqlite3 backend/db/test-restore.sqlite3 "SELECT COUNT(*) FROM Tasks;"
Backup Commands Reference
# Manual backup (development)
cp backend/db/development.sqlite3 backend/db/manual-backup-$(date +%Y%m%d%H%M%S).sqlite3
# Manual backup (production)
cp backend/db/production.sqlite3 backend/db/manual-backup-$(date +%Y%m%d%H%M%S).sqlite3
# List all backups
ls -lh backend/db/db-backup-*.sqlite3
# Restore specific backup
cp backend/db/db-backup-20260314193000.sqlite3 backend/db/development.sqlite3
# Verify backup file integrity
sqlite3 backend/db/db-backup-20260314193000.sqlite3 "PRAGMA integrity_check;"
Troubleshooting
Backup File Not Found
Problem: Can't find automatic backup after startup failure
Solution: Check if database existed before startup. Backups are only created for existing databases.
# New installations won't have backups yet
# First run creates database, second run creates first backup
Restore Fails with "Database is locked"
Problem: SQLite database is locked during restore
Solution: Ensure the application is fully stopped
# Kill all node processes
pkill -f "node.*tududi"
# Verify no processes are using the database
lsof backend/db/development.sqlite3
# Then attempt restore
Large Backup Files
Problem: Backup files consuming too much space
Solution: Automatic cleanup runs on every startup. For manual cleanup:
# Delete backups older than 7 days manually
find backend/db -name "db-backup-*.sqlite3" -mtime +7 -delete
# Or keep only last 10 backups
ls -t backend/db/db-backup-*.sqlite3 | tail -n +11 | xargs rm
Implementation Details
Backup Script Location
The automatic backup script is located at /backend/cmd/start.sh (lines 9-78).
Key functions:
backup_db()- Creates timestamped SQLite file copy- Automatic cleanup based on retention policy
- Runs before every migration
Related Documentation
- Database & Migrations - Schema changes and migrations
- Development Workflow - Database management commands
- Architecture - Data model relationships