Подтвердить что ты не робот

Docker - как я могу скопировать файл с изображения на хост?

Мой вопрос связан с этим вопросом о копировании файлов из контейнеров в хосты; У меня есть Dockerfile, который извлекает зависимости, компилирует артефакт сборки из исходного кода и запускает исполняемый файл. Я также хочу скопировать артефакт сборки (в моем случае это .zip, созданный sbt dist в '../target/`, но я думаю, что этот вопрос также относится к баночкам, двоичным файлам и т.д.

docker cp работает с контейнерами, а не с изображениями; мне нужно запустить контейнер, чтобы извлечь из него файл? В script я попытался запустить /bin/bash в интерактивном режиме в фоновом режиме, скопировав файл, а затем убив контейнер, но это похоже на kludgey. Есть ли лучший способ?

С другой стороны, я хотел бы избежать распаковки файла .tar после запуска docker save $IMAGENAME только для того, чтобы получить один файл (но это похоже на самый простой, хотя и самый медленный вариант).

Я бы использовал объемы докеров, например:

docker run -v hostdir:out $IMAGENAME /bin/cp/../blah.zip /out

но я запускаю boot2docker в OSX, и я не знаю, как напрямую писать в мою файловую систему mac host (объемы чтения и записи монтируются внутри моей загрузочной VMWocker, что означает, что я не могу легко поделиться script извлечь blah.zip из изображения с другими. Мысли?

4b9b3361

Ответ 1

Ответ на старый вопрос для ссылок. Чтобы скопировать файл с изображения, создайте временный контейнер, скопируйте его и удалите его:

id=$(docker create image-name)
docker cp $id:path - > local-tar-file
docker rm -v $id

Ответ 2

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

Однако, если ваше изображение содержит команду cat (и это будет делать во многих случаях), вы можете сделать это с помощью одной команды:

docker run --rm --entrypoint cat yourimage  /path/to/file > path/to/destination

Если ваше изображение не содержит cat, просто создайте контейнер и используйте команду docker cp, как указано в ответе Игоря.

Ответ 3

Гораздо более быстрый вариант - скопировать файл из запущенного контейнера на подключенный том:

docker run -v $PWD:/opt/mount --rm --entrypoint cp image:version /data/libraries.tgz /opt/mount/libraries.tgz

реальный 0m0,446s

** VS **

docker run --rm --entrypoint cat image:version /data/libraries.tgz > libraries.tgz

реальный 0m9.014s

Ответ 4

Родительский комментарий уже показал, как использовать кошку. Вы также можете использовать tar аналогичным образом:

docker run yourimage tar -c -C /my/directory subfolder | tar x

Ответ 5

Я использую boot2docker для MacOS. Могу вас заверить, что сценарии, основанные на "docker cp", переносимы. Поскольку любая команда ретранслируется внутри boot2docker, но затем двоичный поток передается обратно клиенту командной строки докеры, работающему на вашем mac. Таким образом, операции записи с клиента-докера выполняются внутри сервера и записываются обратно в экземпляр исполняемого клиента!

Я использую резервную копию script для томов докеров с любым контейнером докера, который я предоставляю, и мои сценарии резервного копирования протестированы как на Linux, так и на MacOS с помощью boot2docker. Резервные копии могут быть легко обменены между платформами. В основном я выполняю следующую команду внутри моего script:

docker run --name=bckp_for_volume --rm --volumes-from jenkins_jenkins_1 -v /Users/github/jenkins/backups:/backup busybox tar cf /backup/JenkinsBackup-2015-07-09-14-26-15.tar /jenkins

Запускает новый контейнер busybox и монтирует том моего контейнера jenkins с именем jenkins_jenkins_1. Весь том записывается в резервные копии файлов /JenkinsBackup -2015-07-09-14-26-15.tar

Я уже переместил архивы между контейнером linux и контейнером mac без каких-либо настроек для резервного копирования или восстановления script. Если это то, что вы хотите, вы найдете здесь весь script учебник: blacklabelops/jenkins

Ответ 6

Вы можете привязать локальный путь на хосте к пути в контейнере, а затем cp нужные файлы в этот путь в конце вашего скрипта.

$ docker run -d \
  -it \
  --name devtest \
  --mount type=bind,source="$(pwd)"/target,target=/app \
  nginx:latest

Тогда нет необходимости копировать потом.