docker备份整合脚本
之前两篇文章的整合脚本
#命名为 backup_container_all.sh
#运行前:
chmod +x backup_container_all.sh && ./backup_container_all.sh#!/bin/bash
# Define the timestamped backup directory name
timestamp=$(date +"%Y%m%d%H%M%S")
backup_dir="/home/backup_${timestamp}"
# Check if jq is installed
if ! command -v jq &> /dev/null; then
read -p "jq is not installed. Would you like to install it? (y/n) " jq_install
if [[ "$jq_install" == "y" ]]; then
apt update && apt install -y jq
else
echo "jq is required for this script to run. Exiting."
exit 1
fi
fi
# Function to do a backup of all containers' compose files
do_autocompose_all() {
# Create backup directory
mkdir -p "${backup_dir}/all"
# Backup all container configurations into a single compose file
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock ghcr.io/red5d/docker-autocompose $(docker ps -aq) > "${backup_dir}/all/docker-compose-generated.yml"
}
# Function to backup the /root directory
do_backup_root() {
mkdir -p "${backup_dir}/all"
tar -czvf "${backup_dir}/all/root_backup.tar.gz" -C /root .
}
# Function to backup all volumes
do_backup_volumes() {
# Create a temporary directory to store backups of all volumes
local volumes_backup_temp="/tmp/docker_volumes_backup_${timestamp}"
mkdir -p $volumes_backup_temp
# Variable to save the total size of all volumes
total_size=0
# Calculate size of each volume
for volume in $(docker volume ls -q); do
size=$(docker run --rm -v ${volume}:/from_volume busybox du -sh /from_volume 2>/dev/null | cut -f1)
echo "Volume ${volume} size: $size"
total_size=$(($total_size + $(docker run --rm -v ${volume}:/from_volume busybox du -sk /from_volume 2>/dev/null | cut -f1)))
done
# Convert size to appropriate unit
total_size_MB=$(($total_size / 1024))
echo "Total size of all volumes: ${total_size_MB}MB"
# Ask the user for confirmation to proceed
read -p "Do you want to continue with the backup? (y/n) " answer
if [ "$answer" != "y" ]; then
echo "Backup aborted by user."
exit 0
fi
# Backup each individual volume
for volume in $(docker volume ls -q); do
docker run --rm -v ${volume}:/from_volume -v $volumes_backup_temp:/backup busybox tar czf /backup/${volume}.tar.gz -C /from_volume ./
done
# Archive all the individual backup files into one
cd /tmp
tar czf docker_volumes_backup_${timestamp}.tar.gz docker_volumes_backup_${timestamp}
# Show the size of the backup file
echo "Size of the backup: $(du -sh docker_volumes_backup_${timestamp}.tar.gz | cut -f1)"
# Move the archive to the backup directory
mv docker_volumes_backup_${timestamp}.tar.gz "${backup_dir}/all/"
# Cleanup temporary files
rm -rf $volumes_backup_temp
}
# Function to backup an individual container's data
do_individual_container_backup() {
local container_id="$1"
local individual_backup_dir="${backup_dir}/${container_id}"
# Ensure the container backup directory exists
mkdir -p "${individual_backup_dir}"
# Generate docker-compose.yml for the container
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock ghcr.io/red5d/docker-autocompose $container_id > "${individual_backup_dir}/docker-compose.yml"
# Backup volumes associated with the container
local volumes=$(docker inspect $container_id | jq -r '.[0].Mounts[]? | select(.Type == "volume") .Name')
for volume in $volumes; do
docker run --rm -v ${volume}:/from_volume -v ${individual_backup_dir}:/backup busybox tar czf /backup/${volume}.tar.gz -C /from_volume ./
done
# Backup bind mounts associated with the container
local binds=$(docker inspect $container_id | jq -r '.[0].Mounts[]? | select(.Type == "bind") .Source')
for bind in $binds; do
# Exclude all mounts except those under /root/
if [[ $bind == /root/* ]]; then
local bind_name=$(basename $bind)
tar -czvf "${individual_backup_dir}/${bind_name}.tar.gz" -C $bind .
fi
done
}
# ... [前面的代码保持不变] ...
# Main execution wrapped in a loop
while true; do
echo "Choose an option:"
echo "1. Run autocompose-all"
echo "2. Backup /root directory"
echo "3. Backup all volumes"
echo "4. Backup all (1 -> 2 -> 3)"
echo "5. Backup individual container"
echo "6. Continue to backup another container"
echo "7. Exit"
read -p "Enter your choice (1-7): " choice
case $choice in
1)
do_autocompose_all
;;
2)
do_backup_root
;;
3)
do_backup_volumes
;;
4)
do_autocompose_all
do_backup_root
do_backup_volumes
;;
5)
echo "Listing containers..."
IFS=$'\n'
containers=($(docker ps -a --format '{{.ID}}:{{.Names}}'))
unset IFS
for i in "${!containers[@]}"; do
echo "$((i+1))) ${containers[$i]}"
done
read -p "#? " container_choice
if [[ $container_choice -gt 0 && $container_choice -le ${#containers[@]} ]]; then
IFS=':' read -ra selected_container <<< "${containers[$((container_choice-1))]}"
do_individual_container_backup "${selected_container[0]}"
else
echo "Invalid choice."
fi
;;
6)
continue
;;
7)
echo "Exiting..."
exit 0
;;
*)
echo "Invalid choice."
;;
esac
# Prompt to continue or exit after each choice
read -p "Do you want to continue? (y/n) " cont
if [[ $cont != "y" ]]; then
echo "Exiting..."
exit 0
fi
done
注意事项:
脚本使用了
jq命令来解析 Docker 的 JSON 输出。确保已经在服务器上安装了jq。在使用该脚本之前,对其进行一些测试以确保它在你的环境中正确运行是非常重要的。
在脚本中,jq 是用于解析 Docker 容器的详细信息,特别是挂载的卷信息。当你为单个容器备份时,你可能希望知道哪些卷被挂载到了这个容器。因此,我们使用 Docker 的 inspect 命令来获取关于容器的详细信息,这个命令返回一个 JSON 格式的输出。
这是脚本中使用 jq 的相关部分:
volumes=$(docker inspect $container_id | jq -r '.[0].Mounts[]? | select(.Type == "volume") | .Name')这段代码做了以下事情:
使用
docker inspect获取容器的详细信息。使用
jq从 JSON 输出中提取 volume 的名称。.Mounts[]?:遍历所有挂载点。select(.Type == "volume"):从所有挂载点中选择 volume 类型的挂载点。.Name:获取 volume 的名称。
总之,jq 是一个非常强大的命令行 JSON 解析器,允许你从复杂的 JSON 结构中轻松提取信息。在此脚本中,它用于确保我们准确地提取了与容器关联的所有 volumes 的名称。
本文链接:
/archives/1693629887011
版权声明:
本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自
思考题Scotee!
喜欢就支持一下吧