395 Stimmen

Wie erstellt man ein Dockerfile aus einem Image?

Ist es möglich, ein Dockerfile aus einem Image zu generieren? Ich möchte dies 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, Snapshots zu speichern, aber wenn ich fertig bin, wäre es schön, ein strukturiertes Format zu haben, um zu überprüfen, was getan wurde.

257voto

BMW Punkte 38430

Wie generiere oder kehre ich ein Dockerfile von einem Bild um?

Meistens kannst du das.

Anmerkungen: Es generiert kein Dockerfile, das du direkt mit docker build verwenden kannst; die Ausgabe dient nur als Referenz.

alias dfimage="docker run -v /var/run/docker.sock:/var/run/docker.sock --rm alpine/dfimage"
dfimage -sV=1.36 nginx:latest

Es zieht das Ziel-Docker-Image automatisch und exportiert das Dockerfile. Der Parameter -sV=1.36 ist nicht immer erforderlich.

Referenz: https://hub.docker.com/r/alpine/dfimage

Jetzt zeigt hub.docker.com die Bildschichten mit detaillierten Befehlen direkt an, wenn du ein bestimmtes Tag auswählst.

Gib hier eine Bildbeschreibung ein

Bonus

Wenn du wissen möchtest, welche Dateien in jeder Schicht geändert sind

alias dive="docker run -ti --rm -v /var/run/docker.sock:/var/run/docker.sock wagoodman/dive"
dive nginx:latest

Gib hier eine Bildbeschreibung ein

Auf der linken Seite siehst du den Befehl jeder Schicht, auf der rechten Seite (mit Tab wechseln) ist die gelbe Linie der Ordner, in dem einige Dateien in dieser Schicht geändert wurden

(Verwende die LEERTASTE, um das Verzeichnis zu minimieren)

Alte Antwort

Hier ist die alte Antwort, die nicht mehr funktioniert.

$ 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] 
    -f, --full-tree                  Generiere Dockerfile für alle übergeordneten Schichten
    -h, --help                       Zeige diese Nachricht

190voto

user6856 Punkte 2159

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 Image erstellen, aber sie wird nicht alles enthalten, was Sie vollständig verstehen möchten, wie das Image generiert wurde. Vernünftigerweise können Sie die MAINTAINER, ENV, EXPOSE, VOLUME, WORKDIR, ENTRYPOINT, CMD und ONBUILD-Teile der Docker-Datei extrahieren.

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 verwende dies als Teil eines Skripts, um laufende Container als Images neu zu erstellen: https://github.com/docbill/docker-scripts/blob/master/docker-rebase

Das Dockerfile ist hauptsächlich nützlich, wenn Sie ein Image neu verpacken möchten.

Was Sie im Kopf behalten sollten, ist, dass ein Docker-Image tatsächlich nur das Tar-Backup einer realen oder virtuellen Maschine sein kann. Ich habe auf diese Weise mehrere Docker-Images erstellt. Selbst die Baugeschichte zeigt mir, dass ich als ersten Schritt beim Erstellen des Images eine riesige Tar-Datei importiert habe...

98voto

user7610 Punkte 20682

Ich habe den tatsächlichen Befehl in der akzeptierten Antwort irgendwie völlig übersehen, also hier ist er noch einmal, etwas sichtbarer in seinem eigenen Absatz, um zu sehen, wie viele Leute wie ich sind

$ docker history --no-trunc

84voto

fallino Punkte 1321

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

Schritt-für-Schritt-Erklärungen:

tac : Datei umkehren
tr -s ' '                                       mehrere Leerzeichen auf 1 kürzen
cut -d " " -f 5-                                entferne die ersten Felder (bis vor X Monaten/Jahren)
sed 's,^/bin/sh -c #(nop) ,,g'                  entferne /bin/sh-Aufrufe für ENV,LABEL...
sed 's,^/bin/sh -c,RUN,g'                       entferne /bin/sh-Aufrufe für RUN
sed 's, && ,\n  & ,g'                           schönes Formatieren mehrerer Befehlszeilen gemäß den bewährten Docker-Praktiken
sed 's,\s*[0-9]*[\.]*[0-9]*\s*[kMG]*B\s*$,,g'   entferne Informationen zur Layergröße
head -n -1                                      letzte Zeile entfernen ("GRÖßE KOMMENTAR" in diesem Fall)

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"]

20voto

AndrewD Punkte 4319

Update Dez 2018 zur Antwort von BMW

chenzj/dfimage - wie auf hub.docker.com beschrieben - regeneriert das Dockerfile aus anderen Images. Sie können es also wie folgt verwenden:

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X