我一直在用这个Docker-image教程/wordpress演示一个wordpress网站。最近我发现映像使用卷作为mysql数据。

所以问题是这样的:如果我想备份和恢复容器,我可以尝试提交一个映像,然后删除该容器,并从已提交的映像创建一个新容器。但如果我这样做,卷就会被删除,所有的数据都消失了。

一定有一些简单的方法来备份我的容器及其卷数据,但我到处都找不到它。


当前回答

我一直在使用这个批处理脚本备份我所有的卷。该脚本将容器名称作为唯一参数,并自动查找其所有已挂载的卷。

然后它为每个卷创建一个tar存档。

#! /bin/bash

container=$1
dirname="backup-$container-$(date +"%FT%H%M%z")"

mkdir $dirname
cd $dirname

volume_paths=( $(docker inspect $container | jq '.[] | .Mounts[].Name, .Mounts[].Source') )

volume_count=$(( ${#volume_paths[@]} / 2 ))

for i in $(seq $volume_count); do

    volume_name=${volume_paths[i-1]}
    volume_name=$(echo $volume_name | tr -d '"')

    volume_path=${volume_paths[(i-1)+volume_count]}
    volume_path=$(echo $volume_path | tr -d '"')
    echo "$volume_name : $volume_path"

    # create an archive with volume name
    tar -zcvf "$volume_name.tar" $volume_path

done

该代码可在Github上获得。

其他回答

如果你想要一个完整的备份,你需要执行以下几个步骤:

将容器提交给一个映像 保存图像 通过在容器中创建卷的挂载点的tar文件来备份容器的卷。 对数据库容器也重复步骤1-3。

需要注意的是,Docker仅仅将容器提交给镜像,并不包括附加到容器的卷(参考:Docker提交文档)。

提交操作将不包括容器内挂载的卷中包含的任何数据。

下面的命令将在一个装载了所有命名数据卷的容器中运行tar,并将输出重定向到一个文件中:

docker run --rm `docker volume list -q | egrep -v '^.{64}$' | awk '{print "-v " $1 ":/mnt/" $1}'` alpine tar -C /mnt -cj . > data-volumes.tar.bz2

确保测试结果存档,以防出现错误:

tar -tjf data-volumes.tar.bz2
docker container run --rm --volumes-from your_db_container -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /your_named_volume

Run创建新的容器

——rm选项在执行tar CVF /backup/backup.tar /dbdata命令后删除容器

——volumes-from从你在your_db_container中创建的卷中创建一个命名的卷(your_named_volume)

-v $(pwd):/backup在当前主机目录($(pwd))和新容器中的/backup目录之间创建一个绑定挂载

Tar CVF /backup/backup. Tar /your_named_volume创建归档文件

源:备份卷

如果你只需要备份挂载的卷,你可以从Dockerhost复制文件夹。

注意:如果你使用的是Ubuntu, Dockerhost就是你的本地机器。如果你在Mac上,Dockerhost就是你的虚拟机。

在Ubuntu上

你可以在这里找到所有带卷的文件夹:/var/lib/docker/volumes/所以你可以复制它们并在任何你想要的地方存档。

在MAC

它不像Ubuntu那么简单。需要从虚拟机中拷贝文件。

下面是如何从虚拟机(Docker服务器运行的地方)复制所有带卷的文件夹到本地机器的脚本。我们假设您的docker-machine虚拟机名为default。

docker-machine ssh default sudo cp -v -R /var/lib/docker/volumes/ /home/docker/volumes

docker-machine ssh default sudo chmod -R 777 /home/docker/volumes

docker-machine scp -R default:/home/docker/volumes ./backup_volumes

docker-machine ssh default sudo rm -r /home/docker/volumes

它将在当前目录中创建一个文件夹。/backup_volumes,并将所有卷复制到该文件夹中。

下面是一个脚本,演示如何将所有保存的卷从本地目录(./backup_volumes)复制到Dockerhost机器

docker-machine scp -r ./backup_volumes default:/home/docker

docker-machine ssh default sudo mv -f /home/docker/backup_volumes /home/docker/volumes

docker-machine ssh default sudo chmod -R 777 /home/docker/volumes

docker-machine ssh default sudo cp -v -R /home/docker/volumes /var/lib/docker/

docker-machine ssh default sudo rm -r /home/docker/volumes

现在你可以检查它是否工作:

docker volume ls

更新2

原始单卷备份bash脚本:

#!/bin/bash
# This script allows you to backup a single volume from a container
# Data in given volume is saved in the current directory in a tar archive.
CONTAINER_NAME=$1
VOLUME_PATH=$2

usage() {
  echo "Usage: $0 [container name] [volume path]"
  exit 1
}

if [ -z $CONTAINER_NAME ]
then
  echo "Error: missing container name parameter."
  usage
fi

if [ -z $VOLUME_PATH ]
then
  echo "Error: missing volume path parameter."
  usage
fi

sudo docker run --rm --volumes-from $CONTAINER_NAME -v $(pwd):/backup busybox tar cvf /backup/backup.tar $VOLUME_PATH

原始单卷恢复bash脚本:

#!/bin/bash
# This script allows you to restore a single volume from a container
# Data in restored in volume with same backupped path
NEW_CONTAINER_NAME=$1

usage() {
  echo "Usage: $0 [container name]"
  exit 1
}

if [ -z $NEW_CONTAINER_NAME ]
then
  echo "Error: missing container name parameter."
  usage
fi

sudo docker run --rm --volumes-from $NEW_CONTAINER_NAME -v $(pwd):/backup busybox tar xvf /backup/backup.tar

用法可以这样:

$ volume_backup.sh old_container /srv/www
$ sudo docker stop old_container && sudo docker rm old_container
$ sudo docker run -d --name new_container myrepo/new_container
$ volume_restore.sh new_container

假设:备份文件名为backup.tar,与备份恢复脚本在同一目录下,容器之间的卷名称相同。

更新

在我看来,从容器备份卷与从数据容器备份卷没有什么不同。

卷就是链接到容器的路径,所以过程是一样的。

我不知道docker-backup是否也适用于相同的容器卷,但你可以使用:

sudo docker run --rm --volumes-from yourcontainer -v $(pwd):/backup busybox tar cvf /backup/backup.tar /data

and:

sudo docker run --rm --volumes-from yournewcontainer -v $(pwd):/backup busybox tar xvf /backup/backup.tar

最后更新

有一个很好的工具可以让你备份和恢复docker卷容器:

https://github.com/discordianfish/docker-backup

如果你有一个像这样链接到一些容器卷的容器:

$ docker run --volumes-from=my-data-container --name my-server ...

您可以像这样备份所有卷:

$ docker-backup store my-server-backup.tar my-server

然后像这样还原:

$ docker-backup restore my-server-backup.tar

或者你可以按照官方的方式:

如何将只有数据的卷从一个主机移植到另一个主机?