从docker镜像中提取文件?

Bla*_*Bat 63 docker

我想从 Docker 映像中提取文件而不必运行该映像。

docker save选项目前对我来说不是一个可行的选择,因为它只是为了解压缩特定文件而节省了太大的文件。

bbc*_*bbc 92

您可以使用以下命令从图像中提取文件:

docker create $image  # returns container ID
docker cp $container_id:$source_path $destination_path
docker rm $container_id
Run Code Online (Sandbox Code Playgroud)

根据docker create 文档,这不会运行容器:

docker create命令在指定的镜像上创建一个可写的容器层,并为运行指定的命令做好准备。然后将容器 ID 打印到STDOUT。这类似于docker run -d从不启动容器。然后,您可以随时使用该docker start <container_id>命令启动容器。


作为参考(我之前的答案),从图像中提取文件的效率较低的方法如下:

docker run some_image cat $file_path > $output_path
Run Code Online (Sandbox Code Playgroud)

  • 您可能想要覆盖入口点。`docker run --entrypoint /bin/sh my_image -c /bin/cat some_file` (4认同)
  • 这将运行图像,这特别是我在问题中所述的不想做的事情。 (3认同)
  • 我想补充一点,如果您构建的映像没有可运行的命令,那么在运行 docker create 命令时,您可能会收到错误“来自守护程序的错误响应:未指定命令”,在这种情况下,请在图像名称。它可以是“dummycommand”或任何编造的乱码,因为它实际上不会运行。 (3认同)
  • @BlakBat 这个更新的答案对你有用吗?我想我应该创建一个新的答案,但现在已经完成了。 (2认同)
  • @bbc 这个更新后的答案实际上并没有启动一个容器(问题的关键),并且不需要是 root。 (2认同)

Mic*_*rth 9

docker save如果无法存储完整的输出,您可以使用管道从中提取所需的文件。

不幸的是,因为输出是“tar of tars”,所以它可能是一个稍微迭代的过程。

刚才我需要提取文件时我所做的是:

  1. 确定您感兴趣的文件最近更改的图像版本(您如何执行此操作可能取决于您的图像),以及它的创建/保存日期

  2. 使用以下命令从命令的输出中获取完整的目录docker save

    docker 保存 IMAGE_NAME | 焦油-tvf-

  3. 在该命令的输出中查找与layer.tar您在步骤 1 中确定的图像日期匹配的文件。(您可以添加| grep layer.tar以仅显示这些文件)

  4. 将该layer.tar文件提取到标准输出,并获取其目录:

    docker 保存 IMAGE_NAME | tar -xf - -O CHECKSUM_FROM_LIST/layer.tar | tar -xf - -O CHECKSUM_FROM_LIST/layer.tar | tar -xf - -O CHECKSUM_FROM_LIST/layer.tar | 焦油-tvf-

  5. 验证您想要的文件是否已列出,并在找到名称后将其解压缩:

    docker 保存 IMAGE_NAME | tar -xf - -O CHECKSUM_FROM_LIST/layer.tar | tar -xf - -O CHECKSUM_FROM_LIST/layer.tar | tar -xf - -O CHECKSUM_FROM_LIST/layer.tar | tar -xf - 路径/到/您的/文件

如果有多个layer.tar文件与您在步骤 2/3 中查找的日期相匹配,您可能需要对每个文件重复步骤 4,直到找到正确的文件

将上述命令中的大写文本替换为适合您情况的正确图像名称、校验和和文件名。


小智 6

以上都不适合我。完整的工作命令是:

docker run --rm --entrypoint /bin/sh image_name -c "cat /path/filename" > output_filename
Run Code Online (Sandbox Code Playgroud)

没有引号cat传递没有文件名,所以它不知道要显示什么。在命令完成后删除容器也是一个好主意。