我的问题是关于文件从容器复制到主机的问题;我有一个Dockerfile,从源代码获取依赖项,编译构建工件,并运行可执行文件。我还想复制构建工件(在我的情况下,它是由sbt dist在……/target/ ',但我认为这个问题也适用于jar,二进制文件等。

Docker cp工作在容器上,而不是镜像上;我是否需要启动一个容器来获取一个文件?在一个脚本中,我尝试在后台以交互模式运行/bin/bash,复制文件,然后杀死容器,但这似乎很笨拙。有没有更好的办法?

另一方面,我想避免在运行docker save $IMAGENAME后解包一个.tar文件,只是为了得到一个文件(但这似乎是最简单的,如果是最慢的,目前的选项)。

我会使用docker卷,例如:

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

但是我在OSX中运行boot2docker,我不知道如何直接写入我的mac主机文件系统(读写卷挂载在我的boot2docker虚拟机中,这意味着我不能轻松地共享一个脚本来从映像中提取blah.zip。想法吗?


当前回答

一个更快的选择是将文件从运行的容器复制到挂载的卷:

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

真正的0 m0.446s

** vs **

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

真正的0 m9.014s

其他回答

你已经得到了最佳解。让容器为您复制文件,然后在完成时删除自己。

这将从/inside/container/复制文件到您的机器/path/到/hostdir/。

docker run --rm -v /path/to/hostdir:/mnt/out "$IMAGENAME" /bin/cp -r /inside/container/ /mnt/out/

要从映像中复制文件,请创建一个临时容器,从其中复制文件,然后删除它:

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

第一个使用docker pull的docker映像

docker pull <IMG>:<TAG>

然后使用docker create命令创建一个容器,并将容器id存储为一个变量

img_id=$(docker create <IMG>:<TAG>)

现在,运行docker cp命令将docker容器中的文件夹和文件复制到主机上

docker cp $img_id:/path/in/container /path/in/host

一旦文件/文件夹被移动,使用docker rm删除容器

docker rm -v $img_id

这不是对问题细节的直接回答,但通常情况下,一旦您提取了一个图像,图像就存储在您的系统中,它的所有文件也存储在系统中。根据本地Docker安装的存储驱动程序,这些文件通常可以在/var/lib/docker/overlay2中找到(需要root访问)。Overlay2应该是当今最常见的存储驱动程序,但路径可能有所不同。

与图像相关的层可以使用$ docker inspect image IMAGE_NAME:TAG找到,寻找GraphDriver属性。 至少在我的本地环境中,以下也可以快速查看与图像相关的所有图层: docker inspect image IMAGE_NAME:TAG | jq ".[0]. graphdriver . data "

在这些不同的目录中,可以找到所需的文件。 所以从理论上讲,不需要创建临时容器。Ofc这个解决方案非常不方便。

父注释已经展示了如何使用cat。你也可以以类似的方式使用tar:

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