#!/bin/bash # ============================================================================= # Cannamanage — Automated PostgreSQL Backup (GPG encrypted) # ============================================================================= # Usage: ./deploy/backup.sh # Cron: 0 2 * * * /opt/cannamanage/deploy/backup.sh >> /var/log/cannamanage-backup.log 2>&1 # ============================================================================= set -euo pipefail # Load environment if [ -f /opt/cannamanage/.env ]; then set -a source /opt/cannamanage/.env set +a fi BACKUP_DIR="/opt/cannamanage/backups" TIMESTAMP=$(date +%Y%m%d_%H%M%S) DB_CONTAINER="cannamanage-db-1" GPG_RECIPIENT="${BACKUP_GPG_RECIPIENT:-cannamanage-backup}" RETENTION_DAYS="${BACKUP_RETENTION_DAYS:-7}" RETENTION_WEEKS="${BACKUP_RETENTION_WEEKS:-4}" mkdir -p "$BACKUP_DIR/daily" "$BACKUP_DIR/weekly" echo "[$(date)] Starting backup..." # Dump database + compress + encrypt docker exec "$DB_CONTAINER" pg_dump -U "${DB_USER:-cannamanage}" "${DB_NAME:-cannamanage}" | \ gzip | \ gpg --encrypt --recipient "$GPG_RECIPIENT" --trust-model always \ > "$BACKUP_DIR/daily/backup_${TIMESTAMP}.sql.gz.gpg" BACKUP_SIZE=$(du -h "$BACKUP_DIR/daily/backup_${TIMESTAMP}.sql.gz.gpg" | cut -f1) echo "[$(date)] Daily backup completed: backup_${TIMESTAMP}.sql.gz.gpg ($BACKUP_SIZE)" # Weekly backup on Sundays if [ "$(date +%u)" -eq 7 ]; then cp "$BACKUP_DIR/daily/backup_${TIMESTAMP}.sql.gz.gpg" "$BACKUP_DIR/weekly/" echo "[$(date)] Weekly backup copied" fi # Retention: keep N daily, M weekly find "$BACKUP_DIR/daily" -name "*.sql.gz.gpg" -mtime +"$RETENTION_DAYS" -delete find "$BACKUP_DIR/weekly" -name "*.sql.gz.gpg" -mtime +$((RETENTION_WEEKS * 7)) -delete echo "[$(date)] Backup completed successfully. Retention: ${RETENTION_DAYS}d daily, ${RETENTION_WEEKS}w weekly"