#!/usr/bin/env bash # Hourly MinIO mirror for Port Nimara CRM. # # Mirrors the live `MINIO_BUCKET` to the backup destination. `mc mirror` # is incremental — only changed objects transfer — so this is cheap. # # Versioning on the destination bucket is what protects against object # deletes / overwrites; we don't try to roll our own. set -euo pipefail : "${MINIO_ENDPOINT:?MINIO_ENDPOINT not set}" : "${MINIO_ACCESS_KEY:?MINIO_ACCESS_KEY not set}" : "${MINIO_SECRET_KEY:?MINIO_SECRET_KEY not set}" : "${MINIO_BUCKET:?MINIO_BUCKET not set}" : "${BACKUP_S3_BUCKET:?BACKUP_S3_BUCKET not set}" : "${BACKUP_S3_ENDPOINT:?BACKUP_S3_ENDPOINT not set}" : "${BACKUP_S3_ACCESS_KEY:?BACKUP_S3_ACCESS_KEY not set}" : "${BACKUP_S3_SECRET_KEY:?BACKUP_S3_SECRET_KEY not set}" # Default scheme: live MinIO is plain HTTP unless MINIO_USE_SSL=true. LIVE_URL="${MINIO_ENDPOINT}" if [[ "${MINIO_USE_SSL:-false}" == "true" ]]; then LIVE_URL="https://${MINIO_ENDPOINT}:${MINIO_PORT:-443}" else LIVE_URL="http://${MINIO_ENDPOINT}:${MINIO_PORT:-9000}" fi LIVE_ALIAS="live-$$" BACKUP_ALIAS="bk-$$" trap 'mc alias remove "$LIVE_ALIAS" 2>/dev/null || true; mc alias remove "$BACKUP_ALIAS" 2>/dev/null || true' EXIT mc alias set "$LIVE_ALIAS" "$LIVE_URL" \ "$MINIO_ACCESS_KEY" "$MINIO_SECRET_KEY" --api S3v4 >/dev/null mc alias set "$BACKUP_ALIAS" "$BACKUP_S3_ENDPOINT" \ "$BACKUP_S3_ACCESS_KEY" "$BACKUP_S3_SECRET_KEY" --api S3v4 >/dev/null SOURCE="${LIVE_ALIAS}/${MINIO_BUCKET}/" DEST="${BACKUP_ALIAS}/${BACKUP_S3_BUCKET}/minio/" echo "[$(date -u +%FT%TZ)] Mirroring $SOURCE → $DEST" # `--remove` would delete objects from the destination that no longer # exist in source — we DON'T pass it, because that would let an # accidental delete on the live bucket cascade into permanent loss on # the backup side. Versioning + lifecycle handle stale-object cleanup. mc mirror --quiet --overwrite "$SOURCE" "$DEST" # Print byte / count diff for the operator. echo "[$(date -u +%FT%TZ)] Done. Destination summary:" mc du "$DEST"