我的问题是关于文件从容器复制到主机的问题;我有一个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。想法吗?


当前回答

您可以将主机上的本地路径绑定到容器上的路径,然后在脚本的末尾将所需的文件cp到该路径。

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

这样以后就没有必要再抄了。

其他回答

Igor Bukanov回答的PowerShell变体:

$id = & docker create image-name
docker cp ${id}:path - > local-file.tar
docker rm -v $id

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

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

这个问题的另一个(简短的)答案是:

docker run -v $PWD:/opt/mount --rm -ti image:version bash -c "cp /source/file /opt/mount/"

更新-正如@Elytscha Smith所指出的,这只适用于你的映像内置bash

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

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

您可以将主机上的本地路径绑定到容器上的路径,然后在脚本的末尾将所需的文件cp到该路径。

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

这样以后就没有必要再抄了。