it-swarm.com.de

Docker - wie kann ich eine Datei von einem Image auf einen Host kopieren?

Meine Frage bezieht sich auf diese Frage beim Kopieren von Dateien von Containern auf Hosts; Ich habe eine Docker-Datei, die Abhängigkeiten abruft, ein Build-Artefakt aus der Quelle kompiliert und eine ausführbare Datei ausführt. Ich möchte auch das Build-Artefakt kopieren (in meinem Fall ist es ein .Zip, der von sbt dist in '../ target/`erstellt wurde, aber ich denke, diese Frage trifft auch auf Gläser, Binärdateien usw. zu.) 

docker cp funktioniert auf Containern, nicht auf Bildern. muss ich einen Container nur starten, um eine Datei daraus zu erhalten? In einem Skript habe ich versucht, /bin/bash im interaktiven Modus im Hintergrund auszuführen, die Datei zu kopieren und dann den Container zu töten, aber das scheint kludgey zu sein. Gibt es einen besseren Weg?

Andererseits möchte ich vermeiden, dass eine .tar-Datei entpackt wird, nachdem docker save $IMAGENAME ausgeführt wurde, um nur eine Datei herauszuholen (dies scheint jedoch die einfachste, wenn auch langsamste Option zu sein). 

Ich würde Docker-Volumes verwenden, z.

docker run -v hostdir:out $IMAGENAME /bin/cp/../blah.Zip /out

ich arbeite jedoch mit boot2docker in OSX und weiß nicht, wie ich direkt in mein Mac-Host-Dateisystem schreiben soll (Schreib-Lese-Volumes werden in meine boot2docker-VM eingebunden, was bedeutet, dass ich kein Skript zur Freigabe von blah.Zip aus einem Bild mit anderen.

48
Mark

Beantworten einer alten Frage nach Referenzen. Um eine Datei aus einem Bild zu kopieren, erstellen Sie einen temporären Container, kopieren Sie die Datei und löschen Sie sie:

id=$(docker create image-name)
docker cp $id:path - > local-tar-file
docker rm -v $id
89
Igor Bukanov

Leider scheint es keine Möglichkeit zu geben, Dateien direkt von Docker-Images zu kopieren. Sie müssen zuerst einen Container erstellen und dann die Datei aus dem Container kopieren.

Wenn Ihr Image jedoch einen cat-Befehl enthält (was in vielen Fällen der Fall ist), können Sie dies mit einem einzigen Befehl tun:

docker run --rm --entrypoint cat yourimage  /path/to/file > path/to/destination

Wenn Ihr Bild nicht cat enthält, erstellen Sie einfach einen Container und verwenden Sie den docker cp-Befehl, wie in der Antwort von Igor vorgeschlagen.

31
fons

Eine viel schnellere Option ist das Kopieren der Datei aus dem laufenden Container auf einen bereitgestellten Datenträger:

time docker run -v $PWD:/opt/mount --rm --entrypoint cp image:version /data/libraries.tgz /opt/mount/libraries.tgz

echte 0m0.446s

VS 

docker run --rm --entrypoint cat image:version /data/libraries.tgz > libraries.tgz

echte 0m9.014s

8
Mikko

Der Elternkommentar zeigte bereits, wie man cat verwendet. Sie könnten auch tar auf ähnliche Weise verwenden:

docker run yourimage tar -c -C /my/directory subfolder | tar x
8
wedesoft

Ich benutze boot2docker unter MacOS. Ich kann Ihnen versichern, dass Skripte, die auf "docker cp" basieren, portierbar sind. Da jeder Befehl in boot2docker weitergeleitet wird, wird der binäre Datenstrom dann an den Docker-Befehlszeilenclient weitergeleitet, der auf Ihrem Mac ausgeführt wird. Schreibvorgänge vom Docker-Client werden also innerhalb des Servers ausgeführt und in die ausführende Client-Instanz zurückgeschrieben!

Ich teile ein Sicherungsskript für Docker-Volumes mit einem beliebigen Docker-Container, den ich bereitstelle, und meine Sicherungsskripts werden sowohl unter Linux als auch unter MacOS mit boot2docker getestet. Die Backups können einfach zwischen Plattformen ausgetauscht werden. Grundsätzlich führe ich in meinem Skript den folgenden Befehl aus:

docker run --name=bckp_for_volume --rm --volumes-from jenkins_jenkins_1 -v /Users/github/jenkins/backups:/backup busybox tar cf /backup/JenkinsBackup-2015-07-09-14-26-15.tar /jenkins

Führt einen neuen busybox-Container aus und hängt das Volume meines jenkins-Containers mit dem Namen jenkins_jenkins_1. Das gesamte Volume wird in die Dateisicherungen/JenkinsBackup-2015-07-09-14-26-15.tar geschrieben

Ich habe bereits Archive zwischen dem Linux-Container und meinem Mac-Container verschoben, ohne das Backup- oder Restore-Skript anzupassen. Wenn Sie möchten, finden Sie hier das gesamte Skript und ein Tutorial: blacklabelops/jenkins

0
blacklabelops

Sie können binden einen lokalen Pfad auf dem Host an einen Pfad im Container und dann cp die gewünschte (n) Datei (en) an diesen Pfad am Ende Ihres Skripts.

$ docker run -d \
  -it \
  --name devtest \
  --mount type=bind,source="$(pwd)"/target,target=/app \
  nginx:latest

Dann müssen Sie nicht mehr kopieren.

0
ryanjdillon