Skip to main content

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

Next Steps​