Как мне сделать резервную копию и восстановить докеры с именами томов

Я немного путаюсь с функциональностью названных томов в файле docker compose, когда речь заходит о резервном копировании/восстановлении моего приложения.

Я на самом деле проверяю этот файл докеремента:

      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"

Как говорилось в документации, я попытался использовать именованный том вместо контейнера только для данных. Но как я могу сделать резервную копию моих данных?

С контейнером данных я бы выполнил 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 неверно. Он нуждается в точке монтирования внутри контейнера, так что это будет docker run --volume data: /somewhere --volume www: /somewhereelse container_image my_command. Таким образом, это еще сложнее использовать с резервным контейнером.

Итак, каковы лучшие практики в этом случае? Должен ли я использовать только один именованный том для всех моих контейнеров?

Ответ 1

Собственно, это должно быть сделано так же, как указано в официальной документации. Контейнер объема данных хранит данные в "виртуальном корне", поэтому вы должны делать резервную копию следующей командой:

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]

где:

  • --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

где:

  • TEMPORARY_DIRECTORY_STORING_EXTRACTED_BACKUP - это каталог, в который будут скопированы извлеченные файлы (это связано с томом и поэтому будет писать на него)
  • -C - сообщить tar, где извлечь содержимое
  • --strip 1 - удалить ведущие элементы пути (например, родительский каталог, если содержимое резервной копии находится в папке /temp или аналогичной)

Ответ 2

Наконец, я изменил свой подход. Я разбираю тома моих контейнеров, которые ищут точки монтирования, и я делаю резервное копирование всего в отдельной папке в tar.

Поэтому я не использую контейнер для этого, а внешний скрипт. Я не знаю, если это лучший подход, но он работает хорошо.

Ответ 3

Вот пример того, как я могу сделать резервную копию и восстановить данные тома монго как образ докера.

# let a9c25f42ccca be mongo container id    
docker stop a9c25f42ccca

# create a temp container with volume taken from mongo 
# make a local tar archive inside it
docker run --name temp_backup --volumes-from a9c25f42ccca ubuntu tar cvf /mongo_backup.tar /data/db

docker start a9c25f42ccca

# make an image and remove temp container
docker commit temp_backup my_mongo_backup
docker rm temp_backup

# push image with backup to remote registry if needed
docker push my_mongo_backup

И восстановление.

#pull image if needed
docker pull my_mongo_backup

docker stop a9c25f42ccca

# run transient container out from image with backup
# take volume from mongo
# clear any existing data
# restore data from tar arhcive
docker run --rm --volumes-from a9c25f42ccca my_mongo_backup bash -c "rm -rf /data/db/* && tar xvf /mongo_backup.tar -C /data --strip 1"

docker start a9c25f42ccca