我应该如何备份和恢复docker命名卷

Plu*_*lup 25 backup docker-compose

在备份/恢复我的应用程序时,我对docker compose文件中命名卷的功能有点困惑.

我实际上正在测试这个dockercompose文件:

      version: '2'
      services:
          django:
              build: 
                  context: "{{ build_dir }}/docker/django"
              depends_on:
                  - db
              environment:
                  [...]
              volumes:
                  - code:/data/code
                  - www:/var/www
                  - conf:/data/conf
              networks:
                  - front
                  - db
              expose:
                  - "8080"
              entrypoint: "/init"
          db:
              build:
                  context: "{{ build_dir }}/docker/postgres" 
              environment:
                  [...]
              volumes:
                  - data:/var/lib/postgresql/data
              networks:
                  - db

      volumes:
          data:
          www:
          code:
          conf:

      networks:
          front:
              external:
                  name: "proxy_nw"
Run Code Online (Sandbox Code Playgroud)

正如文档所说,我试图使用命名卷而不是仅数据容器.但我怎么想备份我的数据呢?

使用仅数据容器,我会做一个docker run --rm --volume-from DOC backup_container save非常简单的容器.

现在我在这个主题中读到我应该使用类似的东西docker run --rm --volume data --volume www --volume code --volume conf backup_container save.这不是那么简单,因为我有许多具有不同类型和卷名称的应用程序,因此这意味着我保存数据的命令必须对每个应用程序都不同.它使自动化过程复杂化.

编辑:实际上这种语法 docker run --volume data --volume www container_image my_command不正确.它需要容器内的mountpoint,所以它会 docker run --volume data:/somewhere --volume www:/somewhereelse container_image my_command.因此,使用备份容器会更加复杂.

那么,在这种情况下,最佳做法是什么? 我应该只为所有容器使用一个命名卷吗?

小智 41

实际上它应该与官方文档中写的相同.数据卷容器将其数据存储在"虚拟根"中,因此您应该使用下一个命令进行备份:

docker run --rm \ 
  --volume [DOCKER_COMPOSE_PREFIX]_[VOLUME_NAME]:/[TEMPORARY_DIRECTORY_TO_STORE_VOLUME_DATA] \
  --volume $(pwd):/[TEMPORARY_DIRECTORY_TO_STORE_BACKUP_FILE] \
  ubuntu \
  tar cvf /[TEMPORARY_DIRECTORY_TO_STORE_BACKUP_FILE]/[BACKUP_FILENAME].tar /[TEMPORARY_DIRECTORY_TO_STORE_VOLUME_DATA]
Run Code Online (Sandbox Code Playgroud)

哪里:

  • --rm表示将清除为此运行命令创建的映像
  • 默认情况下,DOCKER_COMPOSE_PREFIX是您的项目目录名称
  • VOLUME_NAME是撰写文件中的数据卷容器名称
  • TEMPORARY_DIRECTORY_TO_STORE_VOLUME_DATA是用于装入卷数据的目录
  • TEMPORARY_DIRECTORY_TO_STORE_BACKUP_FILE是虚拟映射到当前目录的目录,其中将放置备份
  • BACKUP_FILENAME - 备份文件的名称(在当前目录中找到它)
  • ubuntu - 您可以使用tar将图像类型更改为另一个容器:)

将数据恢复到卷(还原):

docker run --rm \ 
  --volume [DOCKER_COMPOSE_PREFIX]_[VOLUME_NAME]:/[TEMPORARY_DIRECTORY_STORING_EXTRACTED_BACKUP] \
  --volume $(pwd):/[TEMPORARY_DIRECTORY_TO_STORE_BACKUP_FILE] \
  ubuntu \
  tar xvf /[TEMPORARY_DIRECTORY_TO_STORE_BACKUP_FILE]/[BACKUP_FILENAME].tar -C /[TEMPORARY_DIRECTORY_STORING_EXTRACTED_BACKUP] --strip 1
Run Code Online (Sandbox Code Playgroud)

哪里:

  • TEMPORARY_DIRECTORY_STORING_EXTRACTED_BACKUP是一个将提取的文件复制到的目录(这与卷相关联,因此会写入该文件)
  • -C - 告诉tar提取内容的位置
  • --strip 1 - 删除前导路径元素(例如,如果备份内容位于/ temp文件夹或类似文件中,则为父目录)

  • 出于某种原因,已从官方文档中删除,任何想法为什么? (4认同)
  • 这是我找到的最佳解决方案,但重要的是要知道,如果在容器内使用自定义(非root)用户,访问数据的权限可能会从容器更改为容器.小心这个. (2认同)

小智 7

基于 这个答案。我在这里做了一个简单的工具? docker_named_volume_backup

首先运行命令docker volume ls以列出要备份的命名卷。

然后备份

#sudo backup_docker_volume.sh <volumn_name> <tar_file>
sudo bash ./backup_docker_volume.sh codimd_database-data backup1.tar
Run Code Online (Sandbox Code Playgroud)

用于恢复

#sudo restore_docker_volume.sh <volumn_name> <tar_file>
sudo bash ./restore_docker_volume.sh codimd_database-data backup1.tar
Run Code Online (Sandbox Code Playgroud)