#!/usr/bin/env bash # backup.sh — PostgreSQL backup for Trainingssoftware # # Usage: # DATABASE_URL=postgres://user:pass@host:5432/dbname \ # BACKUP_BUCKET=s3://my-bucket/backups \ # ops/scripts/backup.sh # # Environment variables: # DATABASE_URL (required) — full postgres:// connection string # BACKUP_BUCKET (optional) — s3:// prefix to upload the dump; if unset, # the dump stays in /tmp only # BACKUP_RETENTION_DAYS (optional, default 30) — S3 lifecycle handled externally; # this value is embedded in the # object metadata for auditing set -euo pipefail TIMESTAMP="$(date -u +%Y%m%dT%H%M%SZ)" DUMP_FILE="/tmp/trainingssoftware-${TIMESTAMP}.dump" RETENTION_DAYS="${BACKUP_RETENTION_DAYS:-30}" if [[ -z "${DATABASE_URL:-}" ]]; then echo "ERROR: DATABASE_URL is not set." >&2 exit 1 fi echo "[backup] Starting PostgreSQL dump → ${DUMP_FILE}" pg_dump \ --format=custom \ --compress=9 \ --no-acl \ --no-owner \ "${DATABASE_URL}" \ --file="${DUMP_FILE}" DUMP_SIZE="$(du -sh "${DUMP_FILE}" | cut -f1)" echo "[backup] Dump complete — size: ${DUMP_SIZE}" if [[ -n "${BACKUP_BUCKET:-}" ]]; then S3_KEY="${BACKUP_BUCKET%/}/trainingssoftware-${TIMESTAMP}.dump" echo "[backup] Uploading → ${S3_KEY}" aws s3 cp "${DUMP_FILE}" "${S3_KEY}" \ --metadata "retention_days=${RETENTION_DAYS},timestamp=${TIMESTAMP}" \ --storage-class STANDARD_IA echo "[backup] Upload complete." rm -f "${DUMP_FILE}" else echo "[backup] BACKUP_BUCKET not set — dump kept at ${DUMP_FILE}" fi echo "[backup] Done. timestamp=${TIMESTAMP} size=${DUMP_SIZE}"