cast/scripts/restore-db.sh
claude-hdb a51f0a0156 fix: restore-db.sh connects as the container's Coolify superuser, not "postgres"
Coolify provisions each Postgres resource with a random POSTGRES_USER; the
role "postgres" does not exist, so the hardcoded `psql -U postgres` fails
with FATAL: role "postgres" does not exist. Surfaced by the Task 9 restore
drill against box B. Expand $POSTGRES_USER inside the container (single-quoted
sh -c) so the restore uses the resource's own superuser.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 21:02:57 +00:00

15 lines
1.3 KiB
Bash
Executable file

#!/usr/bin/env bash
# usage: ./scripts/restore-db.sh <artifact.sql.gz> <target-host> <postgres-container> <db-name>
# Streams a Coolify Postgres backup artifact into the target container over
# tailnet SSH. Refuses to run without explicit confirmation of the target.
set -euo pipefail
ARTIFACT="${1:?backup artifact (.sql.gz)}"; HOST="${2:?target host (tailnet name)}"; CONTAINER="${3:?postgres container name}"; DBNAME="${4:?target database name (docker exec <container> env | grep POSTGRES_DB)}"
echo "About to RESTORE ${ARTIFACT} into database ${DBNAME} in ${CONTAINER} on ${HOST} — this overwrites that database."
read -r -p "Type the target host to confirm: " CONFIRM
[ "$CONFIRM" = "$HOST" ] || { echo "confirmation mismatch; aborting"; exit 1; }
# Connect as the container's own superuser: Coolify provisions each Postgres
# resource with a random POSTGRES_USER — "postgres" does not exist. Expand
# $POSTGRES_USER inside the container (single-quoted sh -c), never client-side.
# shellcheck disable=SC2029 # intentional: $CONTAINER/$DBNAME are local vars, expand client-side before they reach the remote shell
gunzip -c "$ARTIFACT" | ssh "root@${HOST}" "docker exec -i ${CONTAINER} sh -c 'psql -U \"\$POSTGRES_USER\" -d ${DBNAME} -v ON_ERROR_STOP=1'"
echo "restore complete — run the verification checks in runbooks/restore-drill.md step 4"