イメージからDockerfileを生成することは可能ですか?2つの理由で知りたい:
リポジトリから画像をダウンロードできますが、画像を生成したレシピを確認したいと思います。
スナップショットを保存するというアイデアは気に入っていますが、完了したら、何が行われたかを確認するための構造化されたフォーマットを用意しておくとよいでしょう。
イメージからDockerfileを生成することは可能ですか?2つの理由で知りたい:
リポジトリから画像をダウンロードできますが、画像を生成したレシピを確認したいと思います。
スナップショットを保存するというアイデアは気に入っていますが、完了したら、何が行われたかを確認するための構造化されたフォーマットを用意しておくとよいでしょう。
回答:
@aleungのコメントからの引用:
centurylink/dockerfile-from-image
新しいバージョンのDockerでは機能しません。これは私のために働きます:hub.docker.com/r/chenzj/dfimage
イメージからDockerfileを生成する方法は?
あなたはできる。
$ 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
これは、存在するイメージからDockerfileを生成する例です selenium/node-firefox-debug
core@core-01 ~ $ docker pull centurylink/dockerfile-from-image
core@core-01 ~ $ alias dfimage="docker run -v /var/run/docker.sock:/var/run/docker.sock --rm centurylink/dockerfile-from-image"
core@core-01 ~ $ dfimage selenium/node-firefox-debug
ADD file:b43bf069650bac07b66289f35bfdaf474b6b45cac843230a69391a3ee342a273 in /
RUN 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
RUN sed -i 's/^#\s*\(deb.*universe\)$/\1/g' /etc/apt/sources.list
CMD ["/bin/bash"]
MAINTAINER Selenium <selenium-developers@googlegroups.com>
RUN echo "deb http://archive.ubuntu.com/ubuntu trusty main universe\n" > /etc/apt/sources.list && echo "deb http://archive.ubuntu.com/ubuntu trusty-updates main universe\n" >> /etc/apt/sources.list
RUN apt-get update -qqy && apt-get -qqy --no-install-recommends install ca-certificates openjdk-7-jre-headless unzip wget && rm -rf /var/lib/apt/lists/* && sed -i 's/\/dev\/urandom/\/dev\/.\/urandom/' ./usr/lib/jvm/java-7-openjdk-amd64/jre/lib/security/java.security
RUN mkdir -p /opt/selenium && wget --no-verbose http://selenium-release.storage.googleapis.com/2.46/selenium-server-standalone-2.46.0.jar -O /opt/selenium/selenium-server-standalone.jar
RUN sudo useradd seluser --shell /bin/bash --create-home && sudo usermod -a -G sudo seluser && echo 'ALL ALL = (ALL) NOPASSWD: ALL' >> /etc/sudoers && echo 'seluser:secret' | chpasswd
MAINTAINER Selenium <selenium-developers@googlegroups.com>
ENV DEBIAN_FRONTEND=noninteractive
ENV DEBCONF_NONINTERACTIVE_SEEN=true
ENV TZ=US/Pacific
RUN echo "US/Pacific" | sudo tee /etc/timezone && dpkg-reconfigure --frontend noninteractive tzdata
RUN apt-get update -qqy && apt-get -qqy install xvfb && rm -rf /var/lib/apt/lists/*
COPY file:335d2f6f9bfe311d2b38034ceab3b2ae2a1e07b9b203b330cac9857d6e17c148 in /opt/bin/entry_point.sh
RUN chmod +x /opt/bin/entry_point.sh
ENV SCREEN_WIDTH=1360
ENV SCREEN_HEIGHT=1020
ENV SCREEN_DEPTH=24
ENV DISPLAY=:99.0
USER [seluser]
CMD ["/opt/bin/entry_point.sh"]
MAINTAINER Selenium <selenium-developers@googlegroups.com>
USER [root]
RUN apt-get update -qqy && apt-get -qqy --no-install-recommends install firefox && rm -rf /var/lib/apt/lists/*
COPY file:52a2a815e3bb6b85c5adfbceaabb5665b63f63ef0fb0e3f774624ee399415f84 in /opt/selenium/config.json
USER [seluser]
MAINTAINER Selenium <selenium-developers@googlegroups.com>
USER [root]
RUN apt-get update -qqy && apt-get -qqy install x11vnc && rm -rf /var/lib/apt/lists/* && mkdir -p ~/.vnc && x11vnc -storepasswd secret ~/.vnc/passwd
ENV LANGUAGE=en_US.UTF-8
ENV LANG=en_US.UTF-8
RUN locale-gen en_US.UTF-8 && dpkg-reconfigure --frontend noninteractive locales && apt-get update -qqy && apt-get -qqy --no-install-recommends install language-pack-en && rm -rf /var/lib/apt/lists/*
RUN apt-get update -qqy && apt-get -qqy --no-install-recommends install fonts-ipafont-gothic xfonts-100dpi xfonts-75dpi xfonts-cyrillic xfonts-scalable && rm -rf /var/lib/apt/lists/*
RUN apt-get update -qqy && apt-get -qqy install fluxbox && rm -rf /var/lib/apt/lists/*
COPY file:90e3a7f757c3df44d541b59234ad4ca996f799455eb8d426218619b244ebba68 in /opt/bin/entry_point.sh
RUN chmod +x /opt/bin/entry_point.sh
EXPOSE 5900/tcp
ここでは、イメージをローカルにプルする必要はなく、コマンドを実行する必要はありません。
上記の画像をサンプルとして使用すると、以下のURLからDockerfileコマンドを取得できます。
https://imagelayers.io/?images=selenium%2Fnode-firefox-debug:latest
しばらく待つと、2つのウィンドウが表示されます。アップウィンドウにはレイヤーが一覧表示され、ダウンウィンドウにはDockerfileのコマンドが一覧表示されます
URLの形式は次のとおりです。
https://imagelayers.io/?images=<USER>%2F<IMAGE>:<TAG>
実際、imagelayers.ioは、 Centurylink
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を明示的に含めていない場合)。
しかし、それは間違いなく便利なものです!この機能を取得するには、2つの方法があります。
これは、の出力形式オプション使用していくつかの調整と単純化して、@の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 node:8 WORKDIR / usr / src / app
COPYファイル:./のe76d2e84545dedbe901b7b7b0c8d2c9733baa07cc821054efec48f623e29218c
RUN / bin / sh -c npm install
コピーdir:a89a4894689a38cbf3895fdc0870878272bb9e09268149a87a6974a274b2184a in。
EXPOSE 8080
CMD ["npm" "start"]