A community based topic aggregation platform built on atproto
1#!/bin/bash
2# Coves Database Backup Script
3# Usage: ./scripts/backup.sh
4#
5# Creates timestamped PostgreSQL backups in ./backups/
6# Retention: Keeps last 30 days of backups
7
8set -e
9
10SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
11PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
12BACKUP_DIR="$PROJECT_DIR/backups"
13COMPOSE_FILE="$PROJECT_DIR/docker-compose.prod.yml"
14
15# Load environment
16set -a
17source "$PROJECT_DIR/.env.prod"
18set +a
19
20# Colors
21GREEN='\033[0;32m'
22YELLOW='\033[1;33m'
23NC='\033[0m'
24
25log() { echo -e "${GREEN}[BACKUP]${NC} $1"; }
26warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
27
28# Create backup directory
29mkdir -p "$BACKUP_DIR"
30
31# Generate timestamp
32TIMESTAMP=$(date +%Y%m%d_%H%M%S)
33BACKUP_FILE="$BACKUP_DIR/coves_${TIMESTAMP}.sql.gz"
34
35log "Starting backup..."
36
37# Run pg_dump inside container
38docker compose -f "$COMPOSE_FILE" exec -T postgres \
39 pg_dump -U "$POSTGRES_USER" -d "$POSTGRES_DB" --clean --if-exists \
40 | gzip > "$BACKUP_FILE"
41
42# Get file size
43SIZE=$(du -h "$BACKUP_FILE" | cut -f1)
44
45log "✅ Backup complete: $BACKUP_FILE ($SIZE)"
46
47# Cleanup old backups (keep last 30 days)
48log "Cleaning up backups older than 30 days..."
49find "$BACKUP_DIR" -name "coves_*.sql.gz" -mtime +30 -delete
50
51# List recent backups
52log ""
53log "Recent backups:"
54ls -lh "$BACKUP_DIR"/*.sql.gz 2>/dev/null | tail -5
55
56log ""
57log "To restore: gunzip -c $BACKUP_FILE | docker compose -f docker-compose.prod.yml exec -T postgres psql -U $POSTGRES_USER -d $POSTGRES_DB"