it-swarm.com.de

Wie erzeugt man eine Dockerfile aus einem Bild?

Ist es möglich, eine Dockerfile aus einem Bild zu generieren? Ich möchte es aus zwei Gründen wissen:

  1. Ich kann Bilder aus dem Repository herunterladen, möchte aber das Rezept sehen, das sie generiert hat.

  2. Ich mag die Idee, Schnappschüsse zu speichern, aber wenn ich fertig bin, wäre es schön, ein strukturiertes Format zu haben, um zu überprüfen, was gemacht wurde.

167
user1026169

Aktualisieren:

Zitat aus @ aleungs Kommentar: 

centurylink/dockerfile-from-image funktioniert nicht mit Docker der neuen Version. Dieser arbeitet für mich: hub.docker.com/r/chenzj/dfimage

Wie erzeugt man eine Dockerfile aus einem Bild?

Sie können. 

Erster Weg

$ 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

Hier ist das Beispiel zum Generieren der Docker-Datei aus einem vorhandenen Image Selenium/node-firefox-debug

[email protected] ~ $ docker pull centurylink/dockerfile-from-image
[email protected] ~ $ alias dfimage="docker run -v /var/run/docker.sock:/var/run/docker.sock --rm centurylink/dockerfile-from-image"
[email protected] ~ $ 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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
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

Eine andere Möglichkeit, die Sie nicht benötigen, um das Image in das lokale Verzeichnis zu ziehen, und es muss kein Befehl ausgeführt werden.

Verwenden Sie das obige Bild als Beispiel. Sie können Dockerfile-Befehle über folgende URL erhalten:

https://imagelayers.io/?images=Selenium%2Fnode-firefox-debug:latest

Warten Sie eine Weile, es werden zwei Fenster angezeigt. Das Aufwärtsfenster listet die Ebenen auf, das Abwärtsfenster listet den Befehl in Dockerfile auf

 imagelayers.io screenshot

Das URL-Format lautet: 

https://imagelayers.io/?images=<USER>%2F<IMAGE>:<TAG>

Im Gesicht wird imagelayers.io von Centurylink erstellt.

77
BMW

Um zu verstehen, wie ein Docker-Image erstellt wurde, verwenden Sie den Befehl docker history --no-trunc.

Sie können eine Docker-Datei aus einem Bild erstellen, diese enthält jedoch nicht alles, was Sie verstehen möchten, wie das Bild generiert wurde. Das, was Sie extrahieren können, sind die Teile MAINTAINER, ENV, EXPOSE, VOLUME, WORKDIR, ENTRYPOINT, CMD und ONBUILD der Dockerfile.

Das folgende Skript sollte für Sie funktionieren:

#!/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"

Ich benutze dies als Teil eines Skripts, um ausgeführte Container als Bilder wiederherzustellen: https://github.com/docbill/docker-scripts/blob/master/docker-rebase

Die Docker-Datei ist vor allem dann nützlich, wenn Sie ein Bild neu verpacken möchten.

Dabei ist zu beachten, dass ein Docker-Image eigentlich nur die Teer-Sicherung einer echten oder virtuellen Maschine sein kann. Ich habe auf diese Weise mehrere Andockbilder gemacht. Sogar der Build-Verlauf zeigt mir, dass ich als ersten Schritt beim Erstellen des Images eine riesige tar-Datei importieren muss ...

130
user6856

Ich habe den eigentlichen Befehl in der akzeptierten Antwort irgendwie absolut verpasst, daher ist es hier wieder etwas sichtbarer in seinem eigenen Absatz, um zu sehen, wie viele Leute wie ich sind

$ docker history --no-trunc <IMAGE_ID>
26
user7610

Eine bash Lösung:

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]*[kMG]*B\s*$,,g' | head -n -1

Schritt für Schritt Erklärungen:

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]*[kMG]*B\s*$,,g'      remove layer size information
head -n -1                                      remove last line ("SIZE COMMENT" in this case)

Beispiel:

 ~  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"]
11
fallino

Es ist zu diesem Zeitpunkt nicht möglich (es sei denn, der Autor des Bildes hat das Dockerfile explizit mit aufgenommen).

Es ist jedoch definitiv etwas Nützliches! Es gibt zwei Dinge, die helfen, diese Funktion zu erhalten.

  1. Vertrauenswürdige Builds (detailliert in diese Docker-Dev-Diskussion
  2. Detailliertere Metadaten in den aufeinanderfolgenden Bildern, die vom Erstellungsprozess erzeugt werden. Auf lange Sicht sollten die Metadaten angeben, von welchem ​​Buildbefehl das Image erzeugt wurde. Dies bedeutet, dass es möglich ist, die Dockerfile aus einer Sequenz von Images zu rekonstruieren.
11
jpetazzo
docker pull chenzj/dfimage


alias dfimage="docker run -v /var/run/docker.sock:/var/run/docker.sock --rm chenzj/dfimage"

dfimage image_id

unten finden Sie die Ausgabe des Befehls dfimage: -

$ dfimage 0f1947a021ce

FROM-Knoten: 8 WORKDIR/usr/src/app

COPY-Datei: e76d2e84545dedbe901b7b7b0c8d2c9733baa07cc821054efec48f623e29218c in ./

RUN/bin/sh -c npm installieren

COPY dir: a89a4894689a38cbf3895fdc0870878272bb9e09268149a87a6974a274b2184a in.

Belichtung 8080

CMD ["npm" "start"]

1
user128364

Update Dezember 2018 auf die Antwort von BMW

docker pull chenzj/dfimage
alias dfimage="docker run -v /var/run/docker.sock:/var/run/docker.sock --rm chenzj/dfimage"
dfimage IMAGE_ID > Dockerfile
0
AndrewD

Dies ergibt sich aus der Antwort von @ fallino, mit einigen Anpassungen und Vereinfachungen durch Verwendung der Ausgabeformat-Option für docker history . Da macOS und Gnu/Linux unterschiedliche Befehlszeilenprogramme haben, ist für Mac eine andere Version erforderlich. Wenn Sie nur die eine oder andere benötigen, können Sie diese Zeilen verwenden.

#!/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
0
Scott Centoni