私たちが協力しているDockerコンテナー用のバックアップと復元のソリューションを構築しようとしています。
私は自分で作成したDockerベースイメージubuntu:base
を持っています。ファイルを追加するためにDockerファイルで毎回それを再構築する必要はありません。
ホストマシンから実行し、ubuntu:base
Dockerイメージを使用して新しいコンテナーを作成し、そのコンテナーにファイルをコピーするスクリプトを作成したいと思います。
ホストからコンテナにファイルをコピーする方法
cp
コマンドを使用してファイルをコピーすることができます。 1つの特定のファイルを次のようにコピーすることができます。
docker cp foo.txt mycontainer:/foo.txt
docker cp mycontainer:/foo.txt foo.txt
強調するために、mycontainer
はcontainerID、notおよびimageID)です。
フォルダsrc
に含まれる複数のファイルは、次のようにしてtarget
フォルダにコピーできます。
docker cp src/. mycontainer:/target
docker cp mycontainer:/src/. target
1.8より前のバージョンのDockerでは、コンテナからホストにファイルをコピーすることしかできませんでした。ホストからコンテナへではありません。
コンテナ名または短いコンテナIDを取得します。
$ docker ps
フルコンテナIDを取得します。
$ docker inspect -f '{{.Id}}' SHORT_CONTAINER_ID-or-CONTAINER_NAME
ファイルをコピーする:
$ 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
最も簡単な方法は、コンテナを起動するときにコンテナにホストディレクトリをマウントすることです。
{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
次はそれを行うのはかなり醜い方法ですがそれは動作します。
docker run -i ubuntu /bin/bash -c 'cat > file' < file
実行中のコンテナでこれを実行する必要がある場合は、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
解決策は以下の通りです。
root@123abc:/root# <-- get the container ID
cp thefile.txt /var/lib/docker/devicemapper/mnt/123abc<bunch-o-hex>/rootfs/root
ファイルはコンテナがファイルシステム上にある場所に直接コピーされなければならない。
実行中のコンテナにファイルをコピーするためのもう1つの解決策は、tarを使用することです。
tar -c foo.sh | docker exec -i theDockerContainer /bin/tar -C /tmp -x
ファイルfoo.sh
をコンテナの/tmp
にコピーします。
編集: Maarten sのコメントのおかげで、還元剤-f
を削除。
新しいdockerfileを作成し、既存の画像をベースとして使用してください。
FROM myName/myImage:latest
ADD myFile.py bin/myFile.py
それからコンテナをビルドします。
docker build .
ファイル をホストから実行中のコンテナにコピーするには
docker exec -i $CONTAINER /bin/bash -c "cat > $CONTAINER_PATH" < $Host_PATH
Erikの回答 およびMiklの、z0rのコメントに基づく
Docker 1.8では、docker cp
はホストからコンテナにファイルをコピーすることができます。 Dockerのブログ記事Docker 1.8の発表:コンテンツの信頼、ツールボックス、レジストリとオーケストレーションの更新を参照してください。
これは、この質問で取り上げられている「ホストから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コンテナーにボリュームを追加する方法を教えてください。。
私はここで(支持された)ほとんどの解決策を試しましたが、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
セクションがあります。 aIMAGE
を使わないでください。
コンテナとローカルファイルシステムの間でファイル/フォルダをコピーするには、次のコマンドを入力します。
docker cp {SOURCE_FILE} {DESTINATION_CONTAINER_ID}:/{DESTINATION_PATH}
例えば、
docker cp /home/foo container-id:/home/dir
Contianer IDを取得するには、指定されたコマンドを入力します。
docker ps
上記の内容は docker.com から取得されます。
コンテナーが既に実行されていると仮定して、指定されたコマンドを入力します。
# 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 ...
注:コンテナーのユーザーはホストのユーザーと同じではないため、許可に関する問題が発生する可能性があります。
Docker環境では、すべてのコンテナはディレクトリにあります。
/var/lib/docker/aufs/required-docker-id/
ソースディレクトリ/ファイルをコンテナの任意の部分にコピーするには、次のコマンドを入力します。
Sudo cp -r mydir/ /var/lib/docker/aufs/mnt/required-docker-id/mnt/
tar
とdocker 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
ホストがCentOSまたはFedoraの場合、/var/lib/docker/aufs
にはプロキシがありませんが、/proc
の下にあります。
cp -r /home/user/mydata/* /proc/$(docker inspect --format "{{.State.Pid}}" <containerid>)/root
このcmdは、data
ディレクトリのすべての内容を、ID "containerid"のコンテナの/
にコピーします。
この質問を見つけた人の多くは、実際にはDockerイメージにファイルをコピーする問題を抱えているかもしれません それが作成されている間 (私はしました)。
その場合は、イメージの作成に使用したCOPY
でDockerfile
コマンドを使用できます。
あなたはあなたのローカルマシンのIPアドレスをたどることができます。
ifconfig
それからDockerコンテナーに入力してタイプしてください。
scp user_name@ip_address:/path_to_the_file destination
いずれにしてもSSHクライアントとサーバーがインストールされていない場合は、次のようにインストールしてください。
Sudo apt-get install openssh-server
私のような人に@ h3nrikの回答のmycontainer
が何を意味するのか明確ではない場合、それは実際にはコンテナ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 ls
またはdocker ps
で取得できます。
良い答えがありますが、具体的すぎます。 docker ps
があなたが興味を持っているコンテナIDを取得するための良い方法であることがわかりました。
mount | grep <id>
ボリュームがマウントされている場所を確認します。それは
/var/lib/docker/devicemapper/mnt/<id>/rootfs/
私にとっては違いますが、OSや設定によっては異なるパスになるかもしれません。ファイルをそのパスにコピーするだけです。
-v
を使用することは常に実用的ではありません。
これはDockerからHostにデータをコピーするコマンドです。
docker cp container_id:file path/filename /hostpath
docker cp a13fb9c9e674:/tmp/dgController.log /tmp/
以下はHostからdockerにデータをコピーするコマンドです。
docker cp a.txt ccfbeb35116b:/home/
私が見つけたコンテナにファイルをコピーするための最良の方法はdocker runコマンドの-v
オプションを使ってホスト上にディレクトリをマウントすることです。
コンテナが置かれている場所から直接ホストマシンからファイルをコピーするだけです。
例えば:
まずコンテナIDを見つけます。
root@**3aed62678d54**:/home#
そしてホストから、ファイルがホームディレクトリにあるとしましょう:
root@saasdock:/home/dnepangue# cp cheering_nasa.gif /var/lib/docker/aufs/mnt/**3aed62678d54**a5df47a4a00a58bb0312009c2902f8a37498a1427052e8ac454b/home/
コンテナに戻る...
root@**3aed62678d54**:/home# ls cheering_nasa.gif
Windowsをホストとして使用している場合は、 WinSCP を使用してDockerに接続し、GUIを介してファイルを転送できます。
Linuxの場合、scp
コマンドも端末を通じて機能します。
コンテナアップ構文
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"
これは、Tomcatコンテナの実行中に単一のファイルをコピーするためのオンラインです。
docker run -v /PATH_TO_WAR/sample.war:/usr/local/Tomcat/webapps/myapp.war -it -p 8080:8080 Tomcat
これにより、warファイルがwebappsディレクトリにコピーされ、すぐにアプリが実行されます。
私は通常このコマンドを使ってpythonサーバを作成します
python -m SimpleHTTPServer
特定のディレクトリに保存してから、wgetを使用してdockerの目的の場所にファイルを転送します。私はそれがそれをする最善の方法ではないことを知っています、しかし私はそれがずっと簡単であると思います。
マウントしてからデーモンでイメージを実行します。
docker run -d -v /blah1/blah2:/mnt --name mntcontainer ubuntu /bin/sh -c "while true; do echo hello world; sleep 1; done"
それから
docker exec -it mntcontainer bash
私の好きな方法:
CONTAINER_ID=$(docker ps | grep <string> | awk '{ print $1 }' | xargs docker inspect -f '{{.Id}}')
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
Dockerを使用してVLCをコンパイルしたところです。コンテナからファイルをコピーする方法は次のとおりです。
su -
cd /var/lib/docker
ls -palR > /home/user/dockerfilelist.txt
そのテキストでおなじみのファイルを検索するとフォルダができます。ルートにしてcdしてください。必要なものをすべてコピーします。
「マージ」されたパスがあるかもしれません。「diff」が含まれているパスが欲しいと思います。
また、コンテナから出て、中断した場所に戻りたい場合も、
docker ps -a
docker start -i containerid
私はあなたがのようなコマンドで何も名前を付けなかったときにそれが役に立つと思います
docker run -it registry.videolan.org:5000/vlc-debian-win64 /bin/bash
ハッカーの方法を確かにしかしそう何!
別の回避策は古き良きscp
を使うことです。これはディレクトリをコピーする必要がある場合に便利です。
あなたのホストから実行します。
scp FILE_PATH_ON_YOUR_Host IP_CONTAINER:DESTINATION_PATH
scp foo.txt 172.17.0.2:foo.txt
この場合、ディレクトリをコピーする必要があります。
scp -r DIR_PATH_ON_YOUR_Host IP_CONTAINER:DESTINATION_PATH
scp -r directory 172.17.0.2:directory
あなたのコンテナにもsshをインストールしてください。
apt-get install openssh-server
私の考えでは、画像内のファイルをコピーする必要はありませんが、ファイルにGITまたはSVNを使用してから、ローカルフォルダと同期するボリュームを設定することができます。 GITリポジトリからコピーしない場合は、ローカルフォルダにデータがすでに存在するかどうかを確認できるコンテナの実行中にスクリプトを使用します。それはあなたのイメージを非常に軽量にします。
Dockerfileでボリュームとして定義されたディレクトリがない場合は、/ var/lib/docker/aufs/mnt //が機能します。しかし、コンテナー内のディレクトリーがボリュームとして定義されている場合があります。この場合、aufs/mnt/* /の下の内容とコンテナーから見た内容は異なります。
Docker inspectを使ってコンテナーを調べてから、ボリュームを探す必要があります。そこには/ var/lib/docker/vfs/dir/fe940b ...(id)のようなものについての言及があります。 aufs/mnt/*の下ではなく、ここにファイルを追加/修正する必要があります。
混乱を招く部分は、ファイルも/ aufs/mnt/*の下に表示されることです。ここでの変更が私にはうまくいかなかった理由私は頭をかいているのにかなりの時間を費やしました。これが誰かに役立つことを願っています。
試してみた1つのこと
Dockerコンテナを起動したら、そのコンテナの下にファイルを作成したら。あなたは簡単にあなたのdocker Hostの下の場所からそのファイルにアクセスすることができます -
一度試してみてください。