ホストからDockerコンテナーへのファイルのコピー


1580

私が使用しているDockerコンテナーのバックアップおよび復元ソリューションを構築しようとしています。

私が作成したDockerベースイメージがubuntu:baseあり、ファイルを追加するためにDockerファイルで毎回再構築する必要はありません。

ホストマシンから実行され、ubuntu:baseDockerイメージを使用して新しいコンテナーを作成し、そのコンテナーにファイルをコピーするスクリプトを作成します。

ホストからコンテナにファイルをコピーするにはどうすればよいですか?


11
再構築したくない場合は、「docker commit」を実行してください。画像が保存されます。
Berend de Boer

27
だれも対処していないという概念についての発言。一般的に、コンテナは「一時的な」ものとして扱います。実行中のコンテナとの間でファイルをコピーするためのユースケースがあります(テスト、プロトタイピング)。しかし、Dockerfileを使用して必要なものを再構築したり、作成したりできない状況にいると、悪い場所にいる可能性があります。通常、コンテナーをOSまたはVMオブジェクトであるかのようにコンテナーをバックアップする必要はありません。一般的に言えば:-)
Scott Prive

回答:


2674

cpこのコマンドは、ファイルをコピーするために使用することができます。

次のように、1つの特定のファイルをコンテナにコピーできます。

docker cp foo.txt mycontainer:/foo.txt

次のように、1つの特定のファイルをコンテナからコピーできます。

docker cp mycontainer:/foo.txt foo.txt

強調のため、mycontainerイメージ ID ではなくコンテナ IDです。

フォルダに含まれている複数のファイルは、次を使用srcしてtargetフォルダにコピーできます。

docker cp src/. mycontainer:/target
docker cp mycontainer:/src/. target

リファレンス:Docker CLI docscp

1.8より前のバージョンのDockerでは、コンテナーからホストにファイルをコピーすることのみが可能でした。ホストからコンテナへではありません。


2
また、これはホストのVMまたはメインOS上にあることに注意してホスト(またはメインOS)にコンテナまたはVMのいずれかのホストで動作します
アダムTuliper - MSFT

7
Dockerfileでは、ADDキーワードを使用して、ビルド時にファイルを追加できます。
0x7d7b 2016年

4
該当COPYするADD場合、@ h3nrikが優先されました。
フランクリンYu

10
を使用docker cpしてコンテナからホストにコピーすることはうまくいきますが、それを使用してファイルをホストからコンテナにコピーしても効果はありません...誰かが理由を知っていますか?dockerバージョン:Dockerバージョン1.10.3、ビルドcb079f6-unsupported
Ace.Yin

2
docker cpを使用して複数のファイルをホストからコンテナーにコピーできますか?
Yogesh

182
  1. コンテナ名または短いコンテナIDを取得します。

    $ docker ps
    
  2. 完全なコンテナIDを取得:

    $ docker inspect -f   '{{.Id}}'  SHORT_CONTAINER_ID-or-CONTAINER_NAME
    
  3. ファイルをコピー:

    $ sudo cp path-file-host /var/lib/docker/aufs/mnt/FULL_CONTAINER_ID/PATH-NEW-FILE
    

例:

$ docker ps

CONTAINER ID      IMAGE    COMMAND       CREATED      STATUS       PORTS        NAMES

d8e703d7e303   solidleon/ssh:latest      /usr/sbin/sshd -D                      cranky_pare

$ docker inspect -f   '{{.Id}}' cranky_pare

または

$ docker inspect -f   '{{.Id}}' d8e703d7e303

d8e703d7e3039a6df6d01bd7fb58d1882e592a85059eb16c4b83cf91847f88e5

$ sudo cp file.txt /var/lib/docker/aufs/mnt/**d8e703d7e3039a6df6d01bd7fb58d1882e592a85059eb16c4b83cf91847f88e5**/root/file.txt

13
私にとって、ホストのマウントパスにはが含まれていませんでしaufsdevicemapper。(実行中に)コンテナーのマウントパスを確認する最も簡単な方法は、コマンドを実行することmountです。
derenio 2014年

3
上記の解決策を試しました。ファイルをドッカー固有のディレクトリにコピーしました。ただし、Dockerコンテナーにbashを使用すると、ファイルがそこに表示されません。何か足りないものはありますか?
AppleBud

2
新しいパスは/ var / lib /
docker

4
私にとっては、ドッカー1.4.1(最新現在)で、それはだ/var/lib/docker/aufs/diff/<id>/
user193130

3
貧しいMacOSユーザーはどうですか?マウントディレクトリは/var/lib私のためにあります。find / -name docker役に立たなかった。
prayagupd 16

141

最もクリーンな方法は、コンテナの起動時にコンテナにホストディレクトリをマウントすることです。

{host} docker run -v /path/to/hostdir:/mnt --name my_container my_image
{host} docker exec -it my_container bash
{container} cp /mnt/sourcefile /path/to/destfile

3
どのようにコンテナーを実行できますか?画像でしかできないと思いました。
Pavel Zaitsev、2015

コンテナーが既存の別名(以前に実行されたもの)である場合、機能しません。下のタールはうまくいきます。
EinoMäkitalo2015

1
これが私にとってうまくいった唯一の方法は、イメージの実行と一緒にボリュームをアタッチすることでした(コンテナーのインスタンス化)。終了docker run -d -p -v /host/path:/mnt --name container_name image_name
ピーターn

2
これは私にはうまくいきません。少なくともコンテナは実行できません。画像のみ実行できます
Shashank Hegde

1
docker cp一方向の操作であることに驚いています。
ThorSummoner 2015

115

以下はかなり醜い方法ですが、うまくいきます。

docker run -i ubuntu /bin/bash -c 'cat > file' < file

7
これはうまくいきます!ただし、変更をコミットすることを忘れないでくださいdocker commit `docker ps -l -q` ubuntu-with-file。それ以外の場合、変更は失われます(代わりに任意の名前を使用してくださいubuntu-with-file
Michael_Scharf '26 / 09/26

@エリック:コンテナーが実行されているときにファイルはどこにありますか?
コアナー

49
ADITIONでは、我々は、新しい使用することができますdocker exec実行中のコンテナで動作するように機能:docker exec -it <container_id> bash -c 'cat > /path/to/container/file' < /path/to/host/file/
Mikl

17
@Mikl ファイルからパイプインするときにTTYがないため、のdocker exec -i ...代わりにすべきだと思い-itます。
z0r 2015年

4
:あなたはまだドッカーの古いバージョンに貼り付け(私はのように)と全体のディレクトリをコピーしたい場合は、この行うことができます tar -c -v -f - /path/to/host/directory | docker exec -i <container-name> bash -c 'tar -x -v --strip-components 1 -f - -C /path/to/container/directory'
eahanson

43

実行中のコンテナーでこれを行う必要がある場合は、docker exec(1.3で追加)を使用できます。

まず、コンテナの名前またはIDを見つけます。

$ docker ps
CONTAINER ID        IMAGE                        COMMAND             CREATED             STATUS              PORTS                   NAMES
b9b7400ddd8f        ubuntu:latest                "/bin/bash"         2 seconds ago       Up 2 seconds                                elated_hodgkin

上記の例では、b9b7400ddd8fまたはを使用できます。elated_hodgkin

/tmp/somefilesホスト上のすべてを/var/wwwコンテナにコピーする場合:

$ cd /tmp/somefiles
$ tar -cv * | docker exec -i elated_hodgkin tar x -C /var/www

次に/bin/bash、コンテナーで実行して、それが機能したことを確認します。

$ docker exec -it elated_hodgkin /bin/bash
root@b9b7400ddd8f:/# ls /var/www
file1  file2

Centos 7.4のdocker 1.16で動作します。
Dudi Boy

41
  1. 新しいdockerfileを作成し、既存のイメージをベースとして使用します。

    FROM myName/myImage:latest
    
    ADD myFile.py bin/myFile.py
    
  2. 次に、コンテナをビルドします。

    docker build .
    

2
これは私のために働いたものです。他には何もありません。ありがとうございました!
オーウェン

新しいコンテナを直接作成するのではなく、新しいイメージを作成します。myFile.pyを変更しながらこのイメージを再利用すると、イメージを再構築しない限り、古いバージョンのファイルが使用されます。
Guillaume Lebreton 2018

リモートサーバーでテストしている場合にのみ、これが最も速い方法です。
ドミニククルラック

これによるとほとんどの人は追加ではなくコピーを使用する必要があります。ただし、ローカルファイルの場合(この例のように)は同等です。
hoosierEE

39

解決策は以下のとおりです、

Dockerシェルから、

root@123abc:/root#  <-- get the container ID

ホストから

cp thefile.txt /var/lib/docker/devicemapper/mnt/123abc<bunch-o-hex>/rootfs/root

ファイルは、コンテナーがファイルシステム上にある場所に直接コピーされます。


10
すばらしい答えです。新しいdockerリリースでは、パスの名前が/ var / lib / docker / aufs / mnt /に変更されました
Alex Volkov

devicemapperパスは、Docker 1.6のfedoraでは機能しないようです。個別のQ、stackoverflow.com / questions / 29939419 /…として記載しました。コメントをいただければ幸いです。
Yogesh_D 2015

33

通常、3つのタイプがあります。

  1. コンテナからホストへ

    docker cp container_id:./bar/foo.txt .
    

dev1

  1. ホストからコンテナへ

    docker exec -i container_id sh -c 'cat > ./bar/foo.txt' < ./foo.txt
    

dev2

  1. コンテナーからコンテナーへの1と2の混合

    docker cp container_id1:./bar/foo.txt .
    
    docker exec -i container_id2 sh -c 'cat > ./bar/foo.txt' < ./foo.txt
    

dev3


6
docker cpは両方の方法で機能します。実行、猫、リダイレクトする必要はありません。docker cp host_file.txt container:/ path /
tbm

32

実行中のコンテナにファイルをコピーする別の解決策は、tarを使用することです。

tar -c foo.sh | docker exec -i theDockerContainer /bin/tar -C /tmp -x

ファイルfoo.shをにコピーします/tmpコンテナに。

編集:Maartenのコメントの-fおかげで、冗長を削除します。


これは、ディレクトリ全体を送信する必要がある場合に適しています。単一のファイルの場合、エリックの答えはより単純です。
ケルビン

1
@ケルビン:しかし、tarはファイルの属性と名前も保持します。特に、名前を入力する必要があるのは1回だけです(シェルからタブ補完が表示されます)。したがって、コンテナーにインストールされている限り、tarは実際にはより単純です。
Maarten

1
これ-f -は少し冗長ですが、デフォルトの動作はとにかくstdoutに書き込むことです。
Maarten

これは、tarにホスト依存があることを意味します
cellige

あなたは正しい-あなたはtarをホスト上とコンテナ内にインストールする必要があります。現在、docker cpを使用する方がより良いソリューションです。
joemat 2016

24

ホストから実行中のコンテナにファイルをコピーするに

docker exec -i $CONTAINER /bin/bash -c "cat > $CONTAINER_PATH" < $HOST_PATH

Erikの回答とMiklとz0rのコメントに基づいています。


承認されたソリューションは、実行中のコンテナに転送するときに、ファイルのインデントを乱すことがあります。これは、このような場合に最適です
Dreams


15

これは、タイトルのこの質問で提起された「ホストからDockerコンテナにファイルをコピーする」という質問に対する直接の回答です。

お試しくださいdocker cp。それが最も簡単な方法で、私のMacでも機能します。使用法:

docker cp /root/some-file.txt some-docker-container:/root

これにより、ホストマシンのsome-file.txtディレクトリ/rootにあるファイルが、ディレクトリに指定some-docker-containerされたDockerコンテナにコピーされます/root。これは、安全なコピー構文に非常に近いものです。そして、前の投稿で示したように、その逆も可能です。つまり、コンテナからホストにファイルもコピーします。

この投稿をダウンリンクする前に、と入力してくださいdocker cp --help。ドキュメントを読むことは非常に役立ちます。時には...

その方法が気に入らず、作成済みで実行中のコンテナーにデータボリュームが必要な場合は、今日、再作成が唯一の選択肢です。ボリュームを既存のDockerコンテナーに追加するにはどうすればよいですか?もご覧ください


15

ここでは(推奨)ソリューションのほとんどを試しましたが、Docker 17.09(2018)では/ var / lib / docker / aufsフォルダーがなくなりました。

このシンプルな方法でdocker cpこのタスクを解決しました。

docker cp c:\path\to\local\file container_name:/path/to/target/dir/

container_nameを取得する方法?

 docker ps 

NAMESセクションがあります。は使用しないでくださいIMAGE


12

コンテナーとローカルファイルシステム間でファイル/フォルダーをコピーするには、次のコマンドを入力します。

docker cp {SOURCE_FILE} {DESTINATION_CONTAINER_ID}:/{DESTINATION_PATH}

例えば、

docker cp /home/foo container-id:/home/dir

contianer IDを取得するには、次のコマンドを入力します。

docker ps

上記のコンテンツはdocker.comから取得しています。


8

コンテナーが既に実行されていると想定して、次のコマンドを入力します。

# cat /path/to/host/file/ | docker exec -i -t <container_id> bash -c "/bin/cat > /path/to/container/file"

共有ディレクトリを使用してファイルを共有するには、次のコマンドを入力してコンテナを実行します。

# docker run -v /path/to/host/dir:/path/to/container/dir ...

注:コンテナーのユーザーはホストのユーザーと同じではないため、権限に関する問題が発生する可能性があります。


1
さらに:docker exec -it <container_id> bash -c 'cat > /path/to/container/file' < /path/to/host/file/
Mikl

2
catいったん終了すると終了しないことに注意してください。それが重要な場合(bashスクリプトをコピーしている場合、bashはスクリプトの実行を拒否します)、そのファイルを保持してlsof | grep yourfilenameいるcatプロセスを実行して強制終了する必要があります。
johndodo 2014年

THX!素晴らしいヒント。このプロセスを1つのコマンドで終了する方法を教えてください。のようなものkill $(lsof | grep /path/to/file | sed ...)。私はあなたの助けに感謝します
Mikl

kill $(docker top CONTAINERNAME | sed -n '/cat$/p' | sed 's/^root[^0-9]\+\([0-9]\+\).*$/\1/')
Mikl 2014年

8

これは、DockerからHostにデータをコピーするコマンドです。

docker cp container_id:file path/filename /hostpath

docker cp a13fb9c9e674:/tmp/dgController.log /tmp/

以下は、ホストからdockerにデータをコピーするコマンドです。

docker cp a.txt ccfbeb35116b:/home/

7

Docker環境では、すべてのコンテナは次のディレクトリにあります。

/var/lib/docker/aufs/required-docker-id/

ソースディレクトリ/ファイルをコンテナの任意の部分にコピーするには、次のコマンドを入力します。

sudo cp -r mydir/ /var/lib/docker/aufs/mnt/required-docker-id/mnt/


5

tardocker cpディレクトリ内のすべてをコピーするための良いコンボです。

データボリュームコンテナーを作成する

docker create --name dvc --volume /path/on/container cirros

ディレクトリ階層を保持するには

tar -c -C /path/on/local/machine . | docker cp - dvc:/path/on/container

仕事をチェック

docker run --rm --volumes-from dvc cirros ls -al /path/on/container

5

ホストがCentOSまたはFedoraの場合、にはないプロキシがありますが、/var/lib/docker/aufs以下にあり/procます:

cp -r /home/user/mydata/* /proc/$(docker inspect --format "{{.State.Pid}}" <containerid>)/root

このコマンドは、IDが「containerid」のコンテナのdataディレクトリにすべてのコンテンツをコピーします/


これはRedhatに固有のものではありません。Debianでも動作します。(多分すべてのGnu / Linuxと/proc)。また、パスを拡張して、ファイルをルートだけでなく別の場所に置きます。
ctrl-alt-delor 2017

5

mycontainer@ h3nrikの答えが何を意味するのかが私のような誰かに明らかでない場合、それは実際にはコンテナIDです。終了したDockerコンテナーから現在のフォルダーにファイルをコピーするWarpSquare.mp4/app/example_scenes/1440p60は、これを使用しました。

docker cp `docker ps -q -l`:/app/example_scenes/1440p60/WarpSquare.mp4 .

ここdocker ps -q -lで、最後に終了したインスタンスのコンテナIDを取得します。場合は、それはあなたがでそれを得ることができる出るコンテナではありませんdocker container lsdocker ps


1
docker ps -aまたはを使用して、終了したコンテナのIDをリストできますdocker container ls -a
0x7d7b


4

次のコマンドを使用して、ローカルマシンのIPアドレスを追跡できます。

ifconfig

次に、Dockerコンテナーに入力して、次のように入力します。

scp user_name@ip_address:/path_to_the_file destination

どの場合でも、SSHクライアントとサーバーがインストールされていない場合は、次のコマンドを使用してインストールします。

sudo apt-get install openssh-server

たくさんありがとう、それは私のためにうまくいきました。プラス、私は他の方法よりも効率的にそれを見つけ
user1314742

これはセキュリティの面で恐ろしいソリューションです。

4

これは、Tomcatコンテナの実行中に単一のファイルをコピーするためのオンラインです。

docker run -v /PATH_TO_WAR/sample.war:/usr/local/tomcat/webapps/myapp.war -it -p 8080:8080 tomcat

これにより、warファイルがwebappsディレクトリにコピーされ、アプリがすぐに実行されます。


1
-vはコピーではなくマウント(リンクを作成)します
Vitaliy Ulantikov

結果の違いは、マウントすると以前のコンテナーコンテンツが非表示になることです。たとえば、ホストフォルダーをコンテナーフォルダーにマウントすると、以前のコンテナーフォルダーコンテンツが表示されなくなります
mrq

4

コンテナアップ構文:

 docker run -v /HOST/folder:/Container/floder 

Dockerファイル内

COPY hom* /myFolder/        # adds all files starting with "hom"
COPY hom?.txt /myFolder/    # ? is replaced with any single character, e.g., "home.txt"

3

私が見つけたコンテナーにファイルをコピーする最良の方法は-v、docker runコマンドのオプションを使用してホストにディレクトリをマウントすることです。


3

良い答えがありますが、具体的すぎます。docker ps興味のあるコンテナーIDを取得するための良い方法を見つけました。次に、

mount | grep <id>

ボリュームがマウントされている場所を確認します。それは

/var/lib/docker/devicemapper/mnt/<id>/rootfs/

私にとっては、それはOSと構成に応じて異なるパスになる場合があります。次に、ファイルをそのパスにコピーします。

使用すること-vは必ずしも実用的ではありません。


3

dockerを使用してVLCをコンパイルし始めました。コンテナーからファイルを前後にコピーするには、次の方法があります。

su -
cd /var/lib/docker
ls -palR > /home/user/dockerfilelist.txt

そのtxtでおなじみのファイルを検索すると、フォルダーが作成され、ルートとしてcdして、出来上がりです!必要なものをすべてコピーします。

「マージ」されたパスがあるかもしれませんが、「diff」が含まれたパスが欲しいと思います。

また、コンテナを終了して、中断したところに戻りたい場合も次のようになります。

docker ps -a
docker start -i containerid

次のようなコマンドで何も名前を付けなかった場合に便利だと思います

docker run -it registry.videolan.org:5000/vlc-debian-win64 /bin/bash

確かにハッカーの方法ですが、それではどうでしょう!


3
docker cp SRC_PATH CONTAINER_ID:DEST_PATH

たとえば、ファイルxxxx / download / jenkinsをtomcatにコピーしたい

コンテナTomcatのIDを取得し始めます

docker ps

CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                    NAMES
63686740b488        tomcat              "catalina.sh run"   12 seconds ago      Up 11 seconds       0.0.0.0:8080->8080/tcp   peaceful_babbage

docker cp xxxx/download/jenkins.war  63686740b488:usr/local/tomcat/webapps/

2

私の好きな方法:

コンテナ:

CONTAINER_ID=$(docker ps | grep <string> | awk '{ print $1 }' | xargs docker inspect -f '{{.Id}}')

file.txt

mv -f file.txt /var/lib/docker/devicemapper/mnt/$CONTAINER_ID/rootfs/root/file.txt

または

mv -f file.txt /var/lib/docker/aufs/mnt/$CONTAINER_ID/rootfs/root/file.txt

devicemapperパスは、Docker 1.6のfedoraでは機能しないようです。個別のQ、stackoverflow.com / questions / 29939419 /…として記載しました。コメントをいただければ幸いです。
Yogesh_D 2015

2

私の意見では、イメージ内のファイルをコピーする必要はありませんが、ファイルにGITまたはSVNを使用して、ローカルフォルダーと同期するボリュームを設定できます。GITリポジトリからコピーしない場合、データがローカルフォルダーに既に存在するかどうかを確認できるコンテナーの実行中にスクリプトを使用します。これにより、イメージが非常に軽量になります。


これはセキュリティリスクのようであり、発生を待つ悪夢にアクセスします。イメージ内からgitリポジトリへのアクセスをどのように提供しますか?それがパブリックリポジトリであると仮定しても、コンテナーが実行されているホストがそのリポジトリにアクセスできると想定します。
tbm

Dockerコンテナー内でgitを使用する場合は同意します。しかし、私たちの場合、スクリプトはホストマシンから実行されています
h.aittamaa
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.