#!/usr/bin/env bash # Restore a Postgres dump produced by backup.sh. # # Usage: # ops/restore.sh /opt/gendesign/backups/gendesign_20260427_033000.sql.gz # # Refuses to run unless RESTORE_CONFIRM=yes is set. This is destructive — # the dump uses --clean --if-exists, so it DROPs existing tables before recreating. # # Example: # RESTORE_CONFIRM=yes ops/restore.sh ./gendesign_20260427_033000.sql.gz set -euo pipefail if [[ "${RESTORE_CONFIRM:-no}" != "yes" ]]; then echo "Refusing to restore — set RESTORE_CONFIRM=yes to proceed." echo "This will DROP existing tables and recreate from the dump." exit 1 fi DUMP_FILE="${1:-}" if [[ -z "$DUMP_FILE" || ! -f "$DUMP_FILE" ]]; then echo "Usage: $0 /path/to/dump.sql.gz" exit 2 fi COMPOSE_DIR=/opt/gendesign COMPOSE_FILE=docker-compose.prod.yml cd "$COMPOSE_DIR" DB_USER=$(docker compose -f "$COMPOSE_FILE" exec -T postgres printenv POSTGRES_USER 2>/dev/null | tr -d '\r' || true) DB_NAME=$(docker compose -f "$COMPOSE_FILE" exec -T postgres printenv POSTGRES_DB 2>/dev/null | tr -d '\r' || true) DB_USER=${DB_USER:-gendesign} DB_NAME=${DB_NAME:-gendesign} echo "Restoring $DUMP_FILE → ${DB_NAME} as ${DB_USER}" gunzip -c "$DUMP_FILE" | \ docker compose -f "$COMPOSE_FILE" exec -T postgres \ psql -U "$DB_USER" -d "$DB_NAME" -v ON_ERROR_STOP=1 echo "Restore complete."