web-dev-qa-db-ja.com

Docker-ファイルを画像からホストにコピーするにはどうすればよいですか?

私の質問は この質問 コンテナからホストへのファイルのコピーに関するものです。依存関係を取得し、ソースからビルドアーティファクトをコンパイルし、実行可能ファイルを実行するDockerfileがあります。ビルドアーティファクトもコピーしたい(私の場合は、 '../target/`の.Zipによって生成されたsbt distですが、この質問はjar、バイナリなどにも適用されると思います。

docker cpは、画像ではなくコンテナで機能します。ファイルを取り出すためにコンテナを起動する必要がありますか?スクリプトで、バックグラウンドで/bin/bashをインタラクティブモードで実行し、ファイルをコピーしてからコンテナーを強制終了しましたが、これは厄介なようです。もっと良い方法はありますか?

一方、.tarを実行した後にdocker save $IMAGENAMEファイルを解凍して、1つのファイルを取り出すことは避けたいと思います(ただし、これは今のところ最も簡単な、もっとも遅いオプションのようです)。

Dockerボリュームを使用します、例:

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

oSXでboot2dockerを実行していますが、mac Hostファイルシステムに直接書き込む方法がわかりません(読み書き可能なボリュームがboot2docker VM内にマウントされているため、スクリプトを簡単に共有できません)他の人と一緒に画像からblah.Zipを抽出します。

71
Mark

参照のための古い質問に答えます。イメージからファイルをコピーするには、一時コンテナーを作成し、そこからファイルをコピーしてから削除します。

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

残念ながら、Dockerイメージから直接ファイルをコピーする方法はないようです。最初にコンテナを作成してから、コンテナからファイルをコピーする必要があります。

ただし、イメージにcatコマンドが含まれている場合(および多くの場合に実行されます)、単一のコマンドで実行できます。

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

画像にcatが含まれていない場合は、コンテナを作成してdocker cp Igorの回答で提案されているコマンド。

41
fons

より高速なオプションは、実行中のコンテナからマウントされたボリュームにファイルをコピーすることです:

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

実数0m0.446s

** VS **

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

実際の0m9.014s

14
Mikko

親のコメントは、すでにcatの使用方法を示しています。同様の方法でtarを使用することもできます。

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

MacOSでboot2dockerを使用しています。 「docker cp」に基づくスクリプトは移植可能であることを保証できます。すべてのコマンドはboot2docker内でリレーされますが、バイナリストリームはMacで実行されているdockerコマンドラインクライアントにリレーされるためです。したがって、Dockerクライアントからの書き込み操作はサーバー内で実行され、実行中のクライアントインスタンスに書き戻されます。

Dockerボリュームのバックアップスクリプトを、提供するすべてのDockerコンテナと共有しています。バックアップスクリプトは、LinuxとMacOSの両方でboot2dockerでテストされています。バックアップはプラットフォーム間で簡単に交換できます。基本的に、スクリプト内で次のコマンドを実行しています。

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

新しいbusyboxコンテナを実行し、jenkins_jenkins_1という名前で私のjenkinsコンテナのボリュームをマウントします。ボリューム全体がファイルbackups/JenkinsBackup-2015-07-09-14-26-15.tarに書き込まれます

バックアップまたは復元スクリプトを調整せずに、LinuxコンテナとMacコンテナ間でアーカイブを既に移動しています。これが必要な場合は、スクリプト全体をチュートリアルで見つけることができます。 blacklabelops/jenkins

0
blacklabelops

バインド ホスト上のローカルパスからコンテナ上のパスに移動し、cpを使用してスクリプトの最後にそのパスに移動します。

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

その後、後でコピーする必要はありません。

0
ryanjdillon