Answers:
如何从映像生成或反转Dockerfile?
您可以。
alias dfimage="docker run -v /var/run/docker.sock:/var/run/docker.sock --rm alpine/dfimage"
dfimage -sV=1.36 nginx:latest
它将自动拉出目标docker映像并导出Dockerfile
。-sV=1.36
并非总是需要该参数。
参考:https : //hub.docker.com/repository/docker/alpine/dfimage
$ docker pull centurylink/dockerfile-from-image
$ alias dfimage="docker run -v /var/run/docker.sock:/var/run/docker.sock --rm centurylink/dockerfile-from-image"
$ dfimage --help
Usage: dockerfile-from-image.rb [options] <image_id>
-f, --full-tree Generate Dockerfile for all parent layers
-h, --help Show this message
要了解如何构建docker映像,请使用
docker history --no-trunc
命令。
您可以从映像构建docker文件,但其中不包含您想完全了解映像是如何生成的所有内容。可以合理地提取的是dockerfile的MAINTAINER,ENV,EXPOSE,VOLUME,WORKDIR,ENTRYPOINT,CMD和ONBUILD部分。
以下脚本适合您:
#!/bin/bash
docker history --no-trunc "$1" | \
sed -n -e 's,.*/bin/sh -c #(nop) \(MAINTAINER .*[^ ]\) *0 B,\1,p' | \
head -1
docker inspect --format='{{range $e := .Config.Env}}
ENV {{$e}}
{{end}}{{range $e,$v := .Config.ExposedPorts}}
EXPOSE {{$e}}
{{end}}{{range $e,$v := .Config.Volumes}}
VOLUME {{$e}}
{{end}}{{with .Config.User}}USER {{.}}{{end}}
{{with .Config.WorkingDir}}WORKDIR {{.}}{{end}}
{{with .Config.Entrypoint}}ENTRYPOINT {{json .}}{{end}}
{{with .Config.Cmd}}CMD {{json .}}{{end}}
{{with .Config.OnBuild}}ONBUILD {{json .}}{{end}}' "$1"
我将其用作脚本的一部分,以将运行中的容器重建为图像:https : //github.com/docbill/docker-scripts/blob/master/docker-rebase
如果您希望能够重新打包映像,则Dockerfile主要有用。
要记住的是,Docker镜像实际上只能是真实或虚拟机的tar备份。我已经用这种方式制作了几个docker镜像。甚至构建历史记录也显示了我导入一个巨大的tar文件作为创建映像的第一步...
Error response from daemon: page not found
我以某种方式绝对错过了接受的答案中的实际命令,所以在这里它在自己的段落中再次可见,以查看有多少人像我一样
$ docker history --no-trunc <IMAGE_ID>
ub.docker.com/r/chenzj/dfimage
呢?这甚至是最近的答案。
docker history
以相反的顺序打印Dockerfile行,并且删除了RUN
指令(您仅获得命令本身,而没有获得RUN
其前面的键)和其他内容,因此您需要手动对其进行编辑才能获得可构建的Dockerfile。其他工具可能会自动为您执行此编辑(我没有尝试过,所以我不知道。)
一个bash解决方案:
docker history --no-trunc $argv | tac | tr -s ' ' | cut -d " " -f 5- | sed 's,^/bin/sh -c #(nop) ,,g' | sed 's,^/bin/sh -c,RUN,g' | sed 's, && ,\n & ,g' | sed 's,\s*[0-9]*[\.]*[0-9]*\s*[kMG]*B\s*$,,g' | head -n -1
逐步说明:
tac : reverse the file
tr -s ' ' trim multiple whitespaces into 1
cut -d " " -f 5- remove the first fields (until X months/years ago)
sed 's,^/bin/sh -c #(nop) ,,g' remove /bin/sh calls for ENV,LABEL...
sed 's,^/bin/sh -c,RUN,g' remove /bin/sh calls for RUN
sed 's, && ,\n & ,g' pretty print multi command lines following Docker best practices
sed 's,\s*[0-9]*[\.]*[0-9]*\s*[kMG]*B\s*$,,g' remove layer size information
head -n -1 remove last line ("SIZE COMMENT" in this case)
例:
~ dih ubuntu:18.04
ADD file:28c0771e44ff530dba3f237024acc38e8ec9293d60f0e44c8c78536c12f13a0b in /
RUN set -xe
&& echo '#!/bin/sh' > /usr/sbin/policy-rc.d
&& echo 'exit 101' >> /usr/sbin/policy-rc.d
&& chmod +x /usr/sbin/policy-rc.d
&& dpkg-divert --local --rename --add /sbin/initctl
&& cp -a /usr/sbin/policy-rc.d /sbin/initctl
&& sed -i 's/^exit.*/exit 0/' /sbin/initctl
&& echo 'force-unsafe-io' > /etc/dpkg/dpkg.cfg.d/docker-apt-speedup
&& echo 'DPkg::Post-Invoke { "rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true"; };' > /etc/apt/apt.conf.d/docker-clean
&& echo 'APT::Update::Post-Invoke { "rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true"; };' >> /etc/apt/apt.conf.d/docker-clean
&& echo 'Dir::Cache::pkgcache ""; Dir::Cache::srcpkgcache "";' >> /etc/apt/apt.conf.d/docker-clean
&& echo 'Acquire::Languages "none";' > /etc/apt/apt.conf.d/docker-no-languages
&& echo 'Acquire::GzipIndexes "true"; Acquire::CompressionTypes::Order:: "gz";' > /etc/apt/apt.conf.d/docker-gzip-indexes
&& echo 'Apt::AutoRemove::SuggestsImportant "false";' > /etc/apt/apt.conf.d/docker-autoremove-suggests
RUN rm -rf /var/lib/apt/lists/*
RUN sed -i 's/^#\s*\(deb.*universe\)$/\1/g' /etc/apt/sources.list
RUN mkdir -p /run/systemd
&& echo 'docker' > /run/systemd/container
CMD ["/bin/bash"]
在这一点上是不可能的(除非映像的作者明确包含Dockerfile)。
但是,这绝对是有用的!有两件事将有助于获得此功能。
这是从@ fallino的回答得出,通过使用输出格式选择一些调整和简化泊坞窗的历史。由于macOS和Gnu / Linux具有不同的命令行实用程序,因此Mac需要不同的版本。如果只需要其中一个,则可以使用这些行。
#!/bin/bash
case "$OSTYPE" in
linux*)
docker history --no-trunc --format "{{.CreatedBy}}" $1 | # extract information from layers
tac | # reverse the file
sed 's,^\(|3.*\)\?/bin/\(ba\)\?sh -c,RUN,' | # change /bin/(ba)?sh calls to RUN
sed 's,^RUN #(nop) *,,' | # remove RUN #(nop) calls for ENV,LABEL...
sed 's, *&& *, \\\n \&\& ,g' # pretty print multi command lines following Docker best practices
;;
darwin*)
docker history --no-trunc --format "{{.CreatedBy}}" $1 | # extract information from layers
tail -r | # reverse the file
sed -E 's,^(\|3.*)?/bin/(ba)?sh -c,RUN,' | # change /bin/(ba)?sh calls to RUN
sed 's,^RUN #(nop) *,,' | # remove RUN #(nop) calls for ENV,LABEL...
sed $'s, *&& *, \\\ \\\n \&\& ,g' # pretty print multi command lines following Docker best practices
;;
*)
echo "unknown OSTYPE: $OSTYPE"
;;
esac
docker pull chenzj/dfimage
alias dfimage="docker run -v /var/run/docker.sock:/var/run/docker.sock --rm chenzj/dfimage"
dfimage image_id
下面是dfimage命令的输出:-
$ dfimage 0f1947a021ce
FROM节点:8 WORKDIR / usr / src / app
COPY文件:./中的e76d2e84545dedbe901b7b7b0c8d2c9733baa07cc821054efec48f623e29218c
运行/ bin / sh -c npm install
COPY dir:中的a89a4894689a38cbf3895fdc0870878272bb9e09268149a87a6974a274b2184a。
展览8080
CMD [“ npm”“开始”]