#!/bin/sh set -eu BACKUP_DIR="${BACKUP_DIR:-/backups}" INTERVAL_SECONDS="${BACKUP_INTERVAL_SECONDS:-86400}" RETENTION_DAYS="${BACKUP_RETENTION_DAYS:-7}" COMPRESSION_LEVEL="${BACKUP_GZIP_LEVEL:-6}" TIMESTAMP_FORMAT="${BACKUP_TIMESTAMP_FORMAT:-%Y-%m-%d_%H-%M-%S}" mkdir -p "$BACKUP_DIR" log() { printf '[backup] %s %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$*" } backup_db() { host="$1" port="$2" db_name="$3" db_user="$4" db_password="$5" prefix="$6" if [ -z "$db_name" ] || [ -z "$db_user" ] || [ -z "$db_password" ]; then log "skip $prefix because DB credentials are incomplete" return 0 fi timestamp="$(date +"$TIMESTAMP_FORMAT")" file_path="$BACKUP_DIR/${prefix}_${timestamp}.sql.gz" log "starting backup for $prefix ($db_name@$host:$port)" PGPASSWORD="$db_password" \ pg_dump \ --host="$host" \ --port="$port" \ --username="$db_user" \ --dbname="$db_name" \ --clean \ --if-exists \ --no-owner \ --no-privileges | gzip "-$COMPRESSION_LEVEL" > "$file_path" log "backup created: $file_path" } cleanup_old_backups() { find "$BACKUP_DIR" -type f -name '*.sql.gz' -mtime +"$RETENTION_DAYS" -delete log "old backups cleanup completed (retention ${RETENTION_DAYS} days)" } run_cycle() { backup_db \ "${POSTGRES_HOST:-postgres}" \ "${POSTGRES_PORT:-5432}" \ "${POSTGRES_DB:-}" \ "${POSTGRES_USER:-}" \ "${POSTGRES_PASSWORD:-}" \ "main" if [ "${BACKUP_INCLUDE_CHAT_DB:-true}" = "true" ]; then backup_db \ "${CHAT_POSTGRES_HOST:-chat-postgres}" \ "${CHAT_POSTGRES_PORT:-5432}" \ "${CHAT_POSTGRES_DB:-}" \ "${CHAT_POSTGRES_USER:-}" \ "${CHAT_POSTGRES_PASSWORD:-}" \ "chat" fi cleanup_old_backups } log "auto-backup service started" while true; do run_cycle log "sleeping for ${INTERVAL_SECONDS} seconds" sleep "$INTERVAL_SECONDS" done