143 lines
3.9 KiB
Markdown
143 lines
3.9 KiB
Markdown
---
|
|
title: Implement Proper Backup Strategies
|
|
impact: LOW-MEDIUM
|
|
impactDescription: Prevents data loss, enables disaster recovery
|
|
tags: production, backup, disaster-recovery, data-protection
|
|
---
|
|
|
|
## Implement Proper Backup Strategies
|
|
|
|
Regular backups are essential for production deployments. PocketBase provides built-in backup functionality and supports external S3 storage.
|
|
|
|
**Incorrect (no backup strategy):**
|
|
|
|
```javascript
|
|
// No backups at all - disaster waiting to happen
|
|
// Just running: ./pocketbase serve
|
|
|
|
// Manual file copy while server running - can corrupt data
|
|
// cp pb_data/data.db backup/
|
|
|
|
// Only backing up database, missing files
|
|
// sqlite3 pb_data/data.db ".backup backup.db"
|
|
```
|
|
|
|
**Correct (comprehensive backup strategy):**
|
|
|
|
```javascript
|
|
// 1. Using PocketBase Admin API for backups
|
|
const adminPb = new PocketBase('http://127.0.0.1:8090');
|
|
await adminPb.collection('_superusers').authWithPassword(admin, password);
|
|
|
|
// Create backup (includes database and files)
|
|
async function createBackup(name = '') {
|
|
const backup = await adminPb.backups.create(name);
|
|
console.log('Backup created:', backup.key);
|
|
return backup;
|
|
}
|
|
|
|
// List available backups
|
|
async function listBackups() {
|
|
const backups = await adminPb.backups.getFullList();
|
|
backups.forEach(b => {
|
|
console.log(`${b.key} - ${b.size} bytes - ${b.modified}`);
|
|
});
|
|
return backups;
|
|
}
|
|
|
|
// Download backup
|
|
async function downloadBackup(key) {
|
|
const token = await adminPb.files.getToken();
|
|
const url = adminPb.backups.getDownloadURL(token, key);
|
|
// url can be used to download the backup file
|
|
return url;
|
|
}
|
|
|
|
// Restore from backup (CAUTION: overwrites current data!)
|
|
async function restoreBackup(key) {
|
|
await adminPb.backups.restore(key);
|
|
console.log('Restore initiated - server will restart');
|
|
}
|
|
|
|
// Delete old backups
|
|
async function cleanupOldBackups(keepCount = 7) {
|
|
const backups = await adminPb.backups.getFullList();
|
|
|
|
// Sort by date, keep newest
|
|
const sorted = backups.sort((a, b) =>
|
|
new Date(b.modified) - new Date(a.modified)
|
|
);
|
|
|
|
const toDelete = sorted.slice(keepCount);
|
|
for (const backup of toDelete) {
|
|
await adminPb.backups.delete(backup.key);
|
|
console.log('Deleted old backup:', backup.key);
|
|
}
|
|
}
|
|
```
|
|
|
|
**Automated backup script (cron job):**
|
|
|
|
```bash
|
|
#!/bin/bash
|
|
# backup.sh - Run daily via cron
|
|
|
|
POCKETBASE_URL="http://127.0.0.1:8090"
|
|
ADMIN_EMAIL="admin@example.com"
|
|
ADMIN_PASSWORD="your-secure-password"
|
|
BACKUP_DIR="/path/to/backups"
|
|
KEEP_DAYS=7
|
|
|
|
# Create timestamp
|
|
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
|
|
|
|
# Create backup via API
|
|
curl -X POST "${POCKETBASE_URL}/api/backups" \
|
|
-H "Authorization: $(curl -s -X POST "${POCKETBASE_URL}/api/collections/_superusers/auth-with-password" \
|
|
-d "identity=${ADMIN_EMAIL}&password=${ADMIN_PASSWORD}" | jq -r '.token')" \
|
|
-d "name=backup_${TIMESTAMP}"
|
|
|
|
# Clean old local backups
|
|
find "${BACKUP_DIR}" -name "*.zip" -mtime +${KEEP_DAYS} -delete
|
|
|
|
echo "Backup completed: backup_${TIMESTAMP}"
|
|
```
|
|
|
|
**Configure S3 for backup storage:**
|
|
|
|
```javascript
|
|
// In Admin UI: Settings > Backups > S3
|
|
// Or via API:
|
|
await adminPb.settings.update({
|
|
backups: {
|
|
s3: {
|
|
enabled: true,
|
|
bucket: 'my-pocketbase-backups',
|
|
region: 'us-east-1',
|
|
endpoint: 's3.amazonaws.com',
|
|
accessKey: process.env.AWS_ACCESS_KEY,
|
|
secret: process.env.AWS_SECRET_KEY
|
|
}
|
|
}
|
|
});
|
|
```
|
|
|
|
**Backup best practices:**
|
|
|
|
| Aspect | Recommendation |
|
|
|--------|---------------|
|
|
| Frequency | Daily minimum, hourly for critical apps |
|
|
| Retention | 7-30 days of daily backups |
|
|
| Storage | Off-site (S3, separate server) |
|
|
| Testing | Monthly restore tests |
|
|
| Monitoring | Alert on backup failures |
|
|
|
|
**Pre-backup checklist:**
|
|
- [ ] S3 or external storage configured
|
|
- [ ] Automated schedule set up
|
|
- [ ] Retention policy defined
|
|
- [ ] Restore procedure documented
|
|
- [ ] Restore tested successfully
|
|
|
|
Reference: [PocketBase Backups](https://pocketbase.io/docs/going-to-production/#backups)
|