Backup & Recovery

Regular backups are essential to protect your data and ensure you can recover from unexpected issues. This guide covers backing up your Broadcast installation and restoring from backups when needed.

Important: Backup Before Upgrades

Always create a backup before upgrading, downgrading, or making significant changes to your Broadcast installation. This ensures you can restore your data if anything goes wrong during the process.

What Gets Backed Up

A complete Broadcast backup includes:

  • Database: All your subscribers, broadcasts, sequences, templates, and settings
  • File uploads: Images, attachments, and other files uploaded to your installation
  • Configuration files: Your environment settings and custom configurations

Automatic Installation Backup

If you installed Broadcast using the automatic installation method, backups are handled automatically.

Creating a Manual Backup

To create a backup manually:

  1. Go to ApplicationBackups in your Broadcast interface
  2. Click Create backup
  3. Wait for the backup process to complete (usually 1-2 minutes)
  4. Download the backup file when prompted

Automatic Backups

Important Note: Automatic scheduled backups are not currently implemented in the standard installation. The installation sets up the infrastructure for backups but does not schedule automatic database backups.

However, the system does include:

  • Manual backup capability via command line
  • Backup retention (keeps only the most recent backup file)
  • Stores backups in /opt/broadcast/db/backups/
  • Can be accessed through the Broadcast interface when created

Command Line Backup

You can also create backups via command line by SSH'ing into your server as root:

# Navigate to the Broadcast directory
cd /opt/broadcast

# Create a database backup (the primary backup method)
./broadcast.sh backup_database

# The backup will be saved to db/backups/ with a timestamp and also copied to app/storage
# Note: The full backup command (./broadcast.sh backup) is not yet implemented

Manual Installation Backup

If you installed Broadcast manually using Docker, you’ll need to handle backups yourself.

Database Backup

Create a PostgreSQL dump of your database:

# Replace 'broadcast' with your database name if different
docker exec postgres pg_dump -U broadcast broadcast_primary_production \
  > backup_$(date +%Y%m%d_%H%M%S).sql

# For a compressed backup
docker exec postgres pg_dump -U broadcast broadcast_primary_production \
  | gzip > backup_$(date +%Y%m%d_%H%M%S).sql.gz

File Backup

Back up your uploaded files and storage:

# Replace paths with your actual volume mount paths
tar -czf files_backup_$(date +%Y%m%d_%H%M%S).tar.gz \
  /path/to/broadcast/storage /path/to/broadcast/uploads

Complete System Backup

For a complete backup, combine database and files:

#!/bin/bash
# backup-broadcast.sh

BACKUP_DIR="/home/your-user/broadcast-backups"
DATE=$(date +%Y%m%d_%H%M%S)

mkdir -p "$BACKUP_DIR"

# Database backup
docker exec postgres pg_dump -U broadcast broadcast_primary_production \
  | gzip > "$BACKUP_DIR/database_$DATE.sql.gz"

# Files backup
tar -czf "$BACKUP_DIR/files_$DATE.tar.gz" \
  /path/to/broadcast/storage /path/to/broadcast/uploads

# Configuration backup
tar -czf "$BACKUP_DIR/config_$DATE.tar.gz" \
  /path/to/broadcast/app/.env /path/to/broadcast/db/.env

echo "Backup completed: $BACKUP_DIR"
ls -la "$BACKUP_DIR"

Make the script executable and run it:

chmod +x backup-broadcast.sh
./backup-broadcast.sh

Restoring from Backup

Warning: Restore Process

Restoring from backup will overwrite your current data. Make sure you have a recent backup of your current state before proceeding.

Automatic Installation Restore

For automatic installations:

  1. Stop the application:
cd /opt/broadcast
./broadcast.sh stop
  1. Restore the database:

The backup files are in custom PostgreSQL format (.dump files inside .tar.gz)

First extract the backup

cd /opt/broadcast/db/backups
tar -xzf broadcast-backup-TIMESTAMP.tar.gz

Restore using pg_restore (since backups use custom format -Fc)

docker exec -i postgres pg_restore -U broadcast \
  -d broadcast_primary_production --clean /backups/broadcast-backup-TIMESTAMP.dump
  1. Restore files (if needed):
# File backups need to be created manually as they're not included in automatic backups
# Extract files backup to the appropriate directories if you have one
tar -xzf files_backup.tar.gz -C /opt/broadcast/
  1. Start the application:
./broadcast.sh start

Note: The automatic installation currently only backs up the database. File backups (uploads, storage) need to be handled manually.

Manual Installation Restore

For manual installations:

  1. Stop the containers:
docker compose -f docker-compose.manual.yml down
  1. Restore the database:
# Start only the postgres container
docker compose -f docker-compose.manual.yml up -d postgres

# Wait for postgres to be ready, then restore
gunzip -c database_backup.sql.gz \
  | docker exec -i postgres psql -U broadcast -d broadcast_primary_production
  1. Restore files:
tar -xzf files_backup.tar.gz -C /path/to/your/broadcast/
  1. Start all services:
docker compose -f docker-compose.manual.yml up -d

Automated Backup Scripts

For Manual Installations

Create a cron job to automate backups:

# Edit your crontab
crontab -e

# Add a line for daily backups at 2 AM
0 2 * * * /path/to/your/backup-broadcast.sh

For Automatic Installations

If you want to set up automatic scheduled backups for automatic installations, you can add a cron job:

# Edit the root crontab
sudo crontab -e

# Add a line for daily database backups at 2 AM
0 2 * * * /opt/broadcast/broadcast.sh backup_database \
  >> /opt/broadcast/logs/cron/backup.log 2>&1

Backup Retention

Automatic Installations: The backup script automatically handles retention by keeping only the most recent backup file. Older backups are automatically deleted.

Manual Installations: To avoid filling up disk space, implement backup retention:

#!/bin/bash
# cleanup-old-backups.sh

BACKUP_DIR="/home/your-user/broadcast-backups"
DAYS_TO_KEEP=7

# Remove files older than specified days
find "$BACKUP_DIR" -name "*.sql.gz" -mtime +$DAYS_TO_KEEP -delete
find "$BACKUP_DIR" -name "*.tar.gz" -mtime +$DAYS_TO_KEEP -delete

echo "Cleaned up backups older than $DAYS_TO_KEEP days"

Best Practices

Backup Frequency

  • Production environments: Daily automated backups
  • Development/testing: Before major changes or weekly
  • Before upgrades: Always create a backup before upgrading

Storage Locations

  • Local storage: Quick access but vulnerable to server failures
  • Remote storage: Upload backups to cloud storage (AWS S3, Google Cloud, etc.)
  • Multiple locations: Keep both local and remote copies

Testing Backups

Regularly test your backup restoration process:

  1. Create a test environment
  2. Restore from a recent backup
  3. Verify all data is intact
  4. Test application functionality

Security

  • Encrypt backups containing sensitive data
  • Secure storage with appropriate access controls
  • Regular rotation of backup encryption keys

Troubleshooting

Common Issues

Database restore fails with permission errors:

# Ensure correct ownership
chown -R broadcast:broadcast /opt/broadcast/

Large backup files:

# Use compression for database backups
pg_dump database_name | gzip > backup.sql.gz

# Split large files if needed
split -b 1000m large_backup.tar.gz backup_part_

Out of disk space:

# Check disk usage
df -h

# Clean up old backups
find /backup/path -name "*.sql.gz" -mtime +7 -delete

Recovery Planning

Create a disaster recovery plan that includes:

  • Backup locations and access procedures
  • Recovery time objectives (how quickly you need to restore)
  • Recovery point objectives (acceptable data loss timeframe)
  • Contact information for technical support
  • Step-by-step restoration procedures

Getting Help

If you need assistance with backup or recovery procedures:

  • Check the troubleshooting section above
  • Review your backup files and error messages
  • Contact support with specific error details and your installation method

Remember: The best backup is the one you never need, but when you do need it, you’ll be grateful it exists.