#!/bin/sh set -eu PROJECT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd) cd "$PROJECT_DIR" CONTAINER_ID=$(docker compose ps -q rustfs) if [ -z "$CONTAINER_ID" ]; then echo "Error: The MineSeeker RustFS service is not running." exit 1 fi VOLUME_NAME=$(docker inspect "$CONTAINER_ID" --format '{{range .Mounts}}{{if eq .Destination "/data"}}{{.Name}}{{end}}{{end}}') if [ -z "$VOLUME_NAME" ]; then echo "Error: Could not determine the RustFS data volume." exit 1 fi BACKUP_DIR=${1:-"$PROJECT_DIR/backups"} mkdir -p "$BACKUP_DIR" BACKUP_DIR=$(CDPATH= cd -- "$BACKUP_DIR" && pwd) TIMESTAMP=$(date +%Y-%m-%d.%H%M%S) BACKUP_FILE="mineseeker-rustfs.${TIMESTAMP}.tar.gz" BACKUP_PATH="$BACKUP_DIR/$BACKUP_FILE" TEMP_PATH="$BACKUP_PATH.tmp" umask 077 APP_WAS_RUNNING=0 SCHEDULER_WAS_RUNNING=0 RUSTFS_WAS_RUNNING=1 [ -z "$(docker compose ps -q app)" ] || APP_WAS_RUNNING=1 [ -z "$(docker compose ps -q scheduler)" ] || SCHEDULER_WAS_RUNNING=1 restart_services() { result=$? rm -f "$TEMP_PATH" [ "$RUSTFS_WAS_RUNNING" -eq 0 ] || docker compose start rustfs || true [ "$APP_WAS_RUNNING" -eq 0 ] || docker compose start app || true [ "$SCHEDULER_WAS_RUNNING" -eq 0 ] || docker compose start scheduler || true return "$result" } trap restart_services EXIT echo "Stopping MineSeeker writers and RustFS for a consistent backup..." docker compose stop app scheduler rustfs echo "Creating RustFS backup: $BACKUP_PATH" docker run --rm \ --volume "$VOLUME_NAME:/data:ro" \ --volume "$BACKUP_DIR:/backup" \ busybox tar czf "/backup/$BACKUP_FILE.tmp" -C /data . mv "$TEMP_PATH" "$BACKUP_PATH" echo "Backup complete: $BACKUP_PATH"