我的问题与将this question文件从容器复制到主机有关;我有一个Dockerfile,它可以获取依赖项,从源代码编译构建工件,并运行可执行文件。我还想复制构建工件(在我的情况下,它是.zip
在' ../ target /`中生成的sbt dist
,但我认为这个问题也适用于jar ,二进制文件等。
docker cp
适用于容器,而非图像;我是否需要启动容器才能获取文件?在脚本中,我尝试在后台以交互模式运行/bin/bash
,将文件复制出来,然后杀死容器,但这看起来很笨拙。还有更好的方法吗?
另一方面,我想避免在运行.tar
之后解压缩docker save $IMAGENAME
文件只是为了获取一个文件(但这似乎是目前最简单的,如果最慢的选项)。
我会使用泊坞窗卷,例如:
docker run -v hostdir:out $IMAGENAME /bin/cp/../blah.zip /out
但是我在OSX中运行boot2docker
并且我不知道如何直接写入我的mac主机文件系统(读写卷正在我的boot2docker VM中安装,这意味着我可以& #39;轻松共享脚本以从其他人的图像中提取blah.zip
。想法?
答案 0 :(得分:96)
回答旧问题以供参考。要从映像复制文件,请创建一个临时容器,从中复制该文件,然后将其删除:
id=$(docker create image-name)
docker cp $id:path - > local-tar-file
docker rm -v $id
答案 1 :(得分:36)
不幸的是,似乎没有一种直接从Docker镜像复制文件的方法。您需要先创建一个容器,然后从容器中复制该文件。
但是,如果您的图像包含cat
命令(在许多情况下它会执行),您可以使用一个命令执行此操作:
docker run --rm --entrypoint cat yourimage /path/to/file > path/to/destination
如果您的图片不包含cat
,只需创建一个容器并按照Igor的回答中的建议使用docker cp
命令。
答案 2 :(得分:13)
更快的选择是将文件从正在运行的容器复制到已安装的卷:
time 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
答案 3 :(得分:9)
家长评论已经展示了如何使用 cat 。您也可以以类似的方式使用 tar :
docker run yourimage tar -c -C /my/directory subfolder | tar x
答案 4 :(得分:4)
此问题的另一个(简短)答案:
docker run -v $PWD:/opt/mount --rm -ti image:version bash -c "cp /source/file /opt/mount/"
更新-如@Elytscha Smith所述,仅当您的图像内置bash时,此功能才有效
答案 5 :(得分:1)
不是对问题详细信息的直接回答,但一般来说,一旦您提取图像,图像就会存储在您的系统中,其所有文件也是如此。根据本地 Docker 安装的存储驱动程序,这些文件通常可以在 /var/lib/docker/overlay2
中找到(需要 root 访问权限)。 overlay2
应该是目前最常见的存储驱动,但路径可能有所不同。
可以使用 $ docker inspect image IMAGE_NAME:TAG
找到与图像关联的图层,查找 GraphDriver
属性。
至少在我的本地环境中,以下还可以快速查看与图像关联的所有图层:
docker inspect image IMAGE_NAME:TAG | jq ".[0].GraphDriver.Data"
在这些 diff
目录之一中,可以找到想要的文件。
所以理论上,没有必要创建一个临时容器。 Ofc这个解决方案很不方便。
答案 6 :(得分:0)
我在MacOS上使用boot2docker。我可以向您保证,基于“docker cp”的脚本是可移植的。因为任何命令都在boot2docker中被中继,但是二进制流被中继回到在mac上运行的docker命令行客户端。因此,docker客户端的写操作在服务器内执行,并写回执行的客户端实例!
我正在与我提供的任何docker容器共享docker卷的备份脚本,我的备份脚本在linux和MacOS上都使用boot2docker进行测试。备份可以在平台之间轻松交换。基本上我在我的脚本中执行以下命令:
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_1安装我的jenkins容器的卷。整个卷将写入文件backups / JenkinsBackup-2015-07-09-14-26-15.tar
我已经在linux容器和我的mac容器之间移动了档案,而没有对备份或恢复脚本进行任何调整。如果这是你想要的,你可以在这里找到整个脚本的教程:blacklabelops/jenkins
答案 7 :(得分:0)
您可以bind主机上的本地路径到容器上的路径,然后cp
在脚本末尾$ docker run -d \
-it \
--name devtest \
--mount type=bind,source="$(pwd)"/target,target=/app \
nginx:latest
到该路径。
custom_objects
然后无需再复制。
答案 8 :(得分:0)
docker cp $(docker create registry.example.com/ansible-base:latest):/home/ansible/.ssh/id_rsa ./hacked_ssh_key
希望提供一线解决方案
编辑:在此解决方案中甚至不必运行容器
答案 9 :(得分:0)
您基本上已经有了最佳解决方案。让容器为您复制文件,然后在完成后自行删除。
这会将文件从 If ThisWorkbook.Sheets("Sheet1").Range("C41").Value = "prime-membership" Then
IE.Document.getElementById("prime-membership").Checked = True
Else
IE.Document.getElementById("non-prime-membership").Checked = True
End If
复制到您位于 /inside/container/
的机器上。
/path/to/hostdir/