curl -sS -O https://raw.githubusercontent.com/cccchiban/BCSB/main/bf.sh  && chmod +x bf.sh && ./bf.sh

脚本尚未经过实际测试,请自行判断是否迁移成功

打包文件保存路径为root/dcc

脚本内容为

#!/bin/bash

install_jq() {
  if ! command -v jq &> /dev/null; then
    echo "jq 未安装,正在自动安装..."
    if [ -x "$(command -v apt-get)" ]; then
      sudo apt-get update
      sudo apt-get install -y jq
    elif [ -x "$(command -v yum)" ]; then
      sudo yum install -y epel-release
      sudo yum install -y jq
    elif [ -x "$(command -v dnf)" ]; then
      sudo dnf install -y jq
    else
      echo "无法检测到包管理器,请手动安装 jq。"
      exit 1
    fi
  fi
}

install_jq

backup_dir="/root/dcc"
volumes_backup_dir="$backup_dir/volumes"
images_backup_dir="$backup_dir/images"
metadata_file="$backup_dir/volumes_metadata.json"
final_backup_file="/root/docker_backup_$(date +%F_%T).tar.gz"

mkdir -p "$volumes_backup_dir"
mkdir -p "$images_backup_dir"

images=$(docker images --format "{{.Repository}}:{{.Tag}}")
for image in $images; do
    tar_filename=$(echo "$image" | tr '/:' '_').tar
    echo "Saving $image as $tar_filename"
    docker save -o "$images_backup_dir/$tar_filename" "$image"
done

echo "All Docker images saved to $images_backup_dir"

echo "[]" > "$metadata_file"

container_ids=$(docker ps -q)
for container_id in $container_ids; do
  mounts=$(docker inspect --format '{{json .Mounts}}' "$container_id")
  if [ "$mounts" != "[]" ]; then
    echo "$mounts" | jq -r '.[] | .Source' | while read -r host_dir; do
      if [ -d "$host_dir" ]; then
        tarball_name=$(basename "$host_dir")
        tarball_path="$volumes_backup_dir/${tarball_name}_$(date +%F_%T).tar.gz"
        echo "Backing up volume: $host_dir -> $tarball_path"
        tar -czf "$tarball_path" -C "$host_dir" .
        
        jq --arg src "$host_dir" --arg tarball "$tarball_path" '. += [{"source": $src, "tarball": $tarball}]' "$metadata_file" > tmp.$$.json && mv tmp.$$.json "$metadata_file"
      else
        echo "Warning: Host directory $host_dir does not exist or is not a directory."
      fi
    done
  fi
done

echo "All Docker volumes saved to $volumes_backup_dir"

tar -czf "$final_backup_file" -C "$backup_dir" .

echo "Backup completed and saved to $final_backup_file"

将镜像下载后上传到新服务器的任意一个路径内

使用脚本

curl -sS -O https://raw.githubusercontent.com/cccchiban/BCSB/main/hf.sh && chmod +x hf.sh && ./hf.sh

输入存储打包镜像的绝对路径,如/root/tcc

脚本内容为

#!/bin/bash


install_jq() {
  if ! command -v jq &> /dev/null; then
    echo "jq 未安装,正在自动安装..."
    if [ -x "$(command -v apt-get)" ]; then
      sudo apt-get update
      sudo apt-get install -y jq
    elif [ -x "$(command -v yum)" ]; then
      sudo yum install -y epel-release
      sudo yum install -y jq
    elif [ -x "$(command -v dnf)" ]; then
      sudo dnf install -y jq
    else
      echo "无法检测到包管理器,请手动安装 jq。"
      exit 1
    fi
  fi
}

install_jq

read -p "Enter the path to the backup tar.gz file: " backup_file

if [ ! -f "$backup_file" ]; then
    echo "Error: File '$backup_file' not found."
    exit 1
fi

restore_dir="/root/dcc"
volumes_restore_dir="$restore_dir/volumes"
images_restore_dir="$restore_dir/images"
metadata_file="$restore_dir/volumes_metadata.json"

mkdir -p "$restore_dir"

tar -xzf "$backup_file" -C "$restore_dir"

cd "$images_restore_dir" || exit
for tar_file in *.tar; do
    echo "Importing image from $tar_file"
    docker load -i "$tar_file"
done

echo "All Docker images imported successfully."

if [ -f "$metadata_file" ]; then
  jq -c '.[]' "$metadata_file" | while read -r entry; do
    src=$(echo "$entry" | jq -r '.source')
    tarball=$(echo "$entry" | jq -r '.tarball')
    if [ -f "$tarball" ]; then
      echo "Restoring volume: $tarball -> $src"
      mkdir -p "$src"  # 确保恢复路径存在
      tar -xzf "$tarball" -C "$src"
    else
      echo "Warning: Tarball $tarball not found."
    fi
  done
else
  echo "Error: Metadata file $metadata_file not found."
fi

echo "All Docker volumes restored successfully."