#!/usr/bin/env bash set -Eeuo pipefail APP_DIR="${APP_DIR:-/opt/proxpanel}" SECRET_FILE="${SECRET_FILE:-$APP_DIR/.backup.env}" CRON_FILE="${CRON_FILE:-/etc/cron.d/proxpanel-db-backup}" BACKUP_LOG="${BACKUP_LOG:-/var/log/proxpanel-db-backup.log}" RESTORE_LOG="${RESTORE_LOG:-/var/log/proxpanel-db-restore-test.log}" usage() { cat <<'EOF' Usage: sudo bash infra/deploy/configure-db-backup-cron.sh [--run-now] Default schedule (UTC): - 02:15 daily: encrypted DB backup - 02:45 daily: restore test against latest encrypted backup EOF } log() { printf '[%s] %s\n' "$(date -u +'%Y-%m-%d %H:%M:%S UTC')" "$*" } die() { printf '[ERROR] %s\n' "$*" >&2 exit 1 } random_key() { openssl rand -hex 64 | tr -d '\n' } main() { local run_now="false" if [[ "${1:-}" == "--run-now" ]]; then run_now="true" elif [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then usage exit 0 elif [[ -n "${1:-}" ]]; then die "Unknown argument: $1" fi [[ "${EUID:-$(id -u)}" -eq 0 ]] || die "Run as root (or with sudo)." [[ -d "$APP_DIR" ]] || die "Missing app dir: $APP_DIR" if [[ ! -f "$SECRET_FILE" ]]; then log "Creating $SECRET_FILE" umask 077 cat >"$SECRET_FILE" <"$CRON_FILE" <<'EOF' SHELL=/bin/bash PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin # Encrypted PostgreSQL backup every day at 02:15 UTC 15 2 * * * root APP_DIR=/opt/proxpanel /opt/proxpanel/infra/deploy/db-backup-encrypted.sh >> /var/log/proxpanel-db-backup.log 2>&1 # Restore test every day at 02:45 UTC 45 2 * * * root APP_DIR=/opt/proxpanel /opt/proxpanel/infra/deploy/db-restore-test.sh >> /var/log/proxpanel-db-restore-test.log 2>&1 EOF chmod 644 "$CRON_FILE" touch "$BACKUP_LOG" "$RESTORE_LOG" chmod 640 "$BACKUP_LOG" "$RESTORE_LOG" if [[ "$run_now" == "true" ]]; then log "Running immediate backup + restore test" APP_DIR="$APP_DIR" "$APP_DIR/infra/deploy/db-backup-encrypted.sh" APP_DIR="$APP_DIR" "$APP_DIR/infra/deploy/db-restore-test.sh" fi log "DB backup/restore cron configured successfully." } main "$@"