Backup Guide
Set up automated backups for Bellamy Book.
In-app backup (admin panel)
The admin panel can run scheduled or manual backups that dump PostgreSQL, MongoDB, Neo4j, and Elasticsearch and upload the archive to object storage. The destination is the same storage provider as media (MinIO or Cloudflare R2). If production uses R2, backups go to the R2 backups bucket automatically — no extra config. See R2 Setup — Backup with R2 for details.
Backup Strategy
Back up:
- PostgreSQL database
- MongoDB database
- Uploaded files
- Configuration files
PostgreSQL Backups
Manual Backup
pg_dump -U bellamyuser -d bellamybook > backup_$(date +%Y%m%d).sql
Automated Backup Script
Create /usr/local/bin/backup-postgres.sh:
#!/bin/bash
BACKUP_DIR="/backups/postgres"
DATE=$(date +%Y%m%d_%H%M%S)
mkdir -p $BACKUP_DIR
pg_dump -U bellamyuser -d bellamybook | gzip > $BACKUP_DIR/backup_$DATE.sql.gz
# Keep only last 30 days
find $BACKUP_DIR -name "backup_*.sql.gz" -mtime +30 -delete
Make it executable:
chmod +x /usr/local/bin/backup-postgres.sh
Cron Job
# Daily backup at 2 AM
0 2 * * * /usr/local/bin/backup-postgres.sh
MongoDB Backups
Manual Backup
mongodump --uri="mongodb://username:password@localhost:27017/bellamybook" --out=/backups/mongo
Automated Backup Script
Create /usr/local/bin/backup-mongo.sh:
#!/bin/bash
BACKUP_DIR="/backups/mongo"
DATE=$(date +%Y%m%d_%H%M%S)
mkdir -p $BACKUP_DIR
mongodump --uri="mongodb://username:password@localhost:27017/bellamybook" \
--out=$BACKUP_DIR/backup_$DATE
# Compress
tar -czf $BACKUP_DIR/backup_$DATE.tar.gz -C $BACKUP_DIR backup_$DATE
rm -rf $BACKUP_DIR/backup_$DATE
# Keep only last 30 days
find $BACKUP_DIR -name "backup_*.tar.gz" -mtime +30 -delete
Cron Job
# Daily backup at 3 AM
0 3 * * * /usr/local/bin/backup-mongo.sh
File Backups
Local Storage Backup
#!/bin/bash
BACKUP_DIR="/backups/files"
DATE=$(date +%Y%m%d_%H%M%S)
mkdir -p $BACKUP_DIR
tar -czf $BACKUP_DIR/files_$DATE.tar.gz /var/www/uploads
# Keep only last 7 days
find $BACKUP_DIR -name "files_*.tar.gz" -mtime +7 -delete
S3 Backup
If using S3, enable versioning and lifecycle policies.
Docker Backups
Backup Script
#!/bin/bash
BACKUP_DIR="/backups"
DATE=$(date +%Y%m%d_%H%M%S)
# PostgreSQL
docker exec postgres pg_dump -U postgres bellamybook | gzip > $BACKUP_DIR/postgres_$DATE.sql.gz
# MongoDB
docker exec mongo mongodump --archive | gzip > $BACKUP_DIR/mongo_$DATE.archive.gz
# Files
docker exec frontend tar -czf - /uploads | gzip > $BACKUP_DIR/files_$DATE.tar.gz
Restore Procedures
Restore PostgreSQL
gunzip < backup_20240101.sql.gz | psql -U bellamyuser -d bellamybook
Restore MongoDB
mongorestore --uri="mongodb://username:password@localhost:27017/bellamybook" \
--archive=backup_20240101.archive.gz --gzip
Restore Files
tar -xzf files_20240101.tar.gz -C /
Remote Backup Storage
S3 Backup
Upload backups to S3:
aws s3 cp backup_$DATE.sql.gz s3://your-backup-bucket/postgres/
rsync to Remote Server
rsync -avz /backups user@backup-server:/remote-backups/
Backup Verification
Test Restores
Regularly test restore procedures:
# Test restore to temporary database
createdb test_restore
gunzip < backup.sql.gz | psql -d test_restore
# Verify data
psql -d test_restore -c "SELECT COUNT(*) FROM posts;"
dropdb test_restore
Monitoring
Backup Status Monitoring
Check backup success:
#!/bin/bash
LAST_BACKUP=$(find /backups -name "*.sql.gz" -mtime -1)
if [ -z "$LAST_BACKUP" ]; then
echo "WARNING: No backup found in last 24 hours"
# Send alert
fi