从Docker容器中提取Dockerfile是否可行?

48

我刚开始学习Docker,能够查看用于创建现有Docker镜像的Dockerfiles将非常有帮助。

即使该镜像是通过手动运行命令,然后提交到标签中构建的,也很好能够查看镜像的制作方式,既可以用于学习目的,也可以用于安全性考虑。

是否有一种方法可以提取一个Dockerfile或列出用于构建给定Docker镜像的命令?


编辑(2021年11月):由于人们仍在投票,因此根据答案和评论,我选择了:

docker history --no-trunc --format '{{.CreatedBy}}' <image> | grep -v '#(nop)' | tac

它生成输出,便于放入Dockerfile中。例如:

$ docker history --no-trunc --format '{{.CreatedBy}}' qemu | grep -v '#(nop)' | tac
ENV DEBIAN_FRONTEND=noninteractive
RUN /bin/sh -c apt-get update && apt-get -y upgrade # buildkit
RUN /bin/sh -c apt install -y qemu-system-arm gcc-arm-none-eabi build-essential cmake bison flex # buildkit
RUN /bin/sh -c useradd --create-home qemu # buildkit
WORKDIR /home/qemu
USER qemu
COPY baremetal-arm baremetal-arm # buildkit

但是,正如我之前所写的那样,我不认为有一种好的方法可以提取Dockerfile,所以如果你需要它,并且找不到源代码,或许可以跳过这个镜像。


这个回答解决了你的问题吗?如何从一个镜像生成Dockerfile? - user7610
@user7610 不是很准确 :) 自从我问那个问题以来,我已经走了很长的路。 "docker history" 当时还可以,但由于现在可以压缩层,我的结论是现在没有完美的方法来做到这一点。 - mhvelplund
3个回答

48

你有一个非常有用的命令docker history <镜像>。如果其中没有步骤涉及stdin,甚至可以用它来生成一个dockerfile。

如果有步骤涉及stdin,则唯一了解发生情况的方法是执行docker logs <上级容器ID>,但如果没有该容器,你就无法这样做。


7
使用 docker history --no-trunc 命令,以便查看“全部”信息。 - user7610
6
对我来说,docker history --no-trunc --format 'RUN {{.CreatedBy}}' <image> 是最好的选择。 - FUJI Goro

16

现在有undocker可用。

我们可以使用pip命令安装它。

pip install git+https://github.com/larsks/undocker/ 

使用

docker save IMAGE_NAME | undocker -i -o OUTPUT_DIR
从Docker中提取文件。

https://github.com/larsks/undocker/


2
这个工具似乎不能完成所要求的任务,即如何重新创建Dockerfile。它只是从Docker容器中解压文件。 - rgov
@rgov 这个问题是要从 Docker 文件中提取内容,而不是重新创建它。 - Dinesh
1
该请求是“查看用于创建现有 Docker 镜像的 Dockerfiles。” Dockerfile 是用于创建图像的一组步骤(COPYRUNENV 等)。它不是容器文件系统的内容。 - rgov

3

有一个项目dockerfile-from-image可以直接帮助您完成此操作。

只需运行以下CLI命令即可恢复Dockerfile:

docker run -v /var/run/docker.sock:/var/run/docker.sock centurylink/dockerfile-from-image <IMAGE_TAG_OR_ID>

需要预先安装Docker。


11
无法运行: /usr/lib/ruby/gems/2.2.0/gems/docker-api-1.24.1/lib/docker/connection.rb:42:in `rescue in request': 400 Bad Request: malformed Host header (Docker::Error::ClientError) - Julianesten
这对我在Linux上使用重建的(但使用相同的dockerfile)镜像dduvnjak/dockerfile-from-image有些作用,请参见此处的问题https://github.com/CenturyLinkLabs/dockerfile-from-image/issues/14。看起来依赖项需要更新以考虑协议更改。也就是说,这不是一个完整的解决方案-至少从我的特定测试中,它不会重新构建`VOLUME`和`ENTRYPOINT`指令,并且来自该图像构建步骤的文件只是被引用为“从另一个图像中提取”。因此,这是非常复杂的dockerfile过程中的部分步骤。 - mbafford

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接