Docker ADDとVOLUME


116

私はDockerを学習していますがADD、いつ、どこで、を使用するかについて疑問がありVOLUMEます。これらはどちらも私が思うことです:

追加

ビルド時にファイルをイメージにコピーします。イメージにはすべてのファイルが含まれているため、非常に簡単にデプロイできます。一方、ビルドでは開発者がコンテナを再ビルドするコマンドを実行する必要があるため、毎回ビルドする必要があることは、開発において良いアイデアのようには見えません。さらに、コンテナの構築には時間がかかる場合があります。

ボリューム

使用docker run -vすると、コンテナー内にホストフォルダーをマウントできるため、ファイルを簡単に変更し、コンテナー内のアプリが変更に反応するのを確認できます。開発上はすばらしいように見えますが、この方法でファイルをデプロイする方法はわかりません。


3
一般的には、を優先COPYすることをお勧めしADDます。それらはほとんど同じですADDが、驚くべきことに、URLとアーカイブファイルに対していくつかの追加機能があります。
Adrian Mouat、2015年

2
@jamesmstone-そのリンク(および公式のDockerドキュメント)は反対を推奨しています。ADDではなくCOPYを使用してください。
ソフトウェアエンジニア

おっと、あなたは正しい-乾杯!
jamesmstone 2018

回答:


183

追加

これら2つの基本的な違いはADD、フォルダーでもファイルでも、実際に画像の一部であるということです。後で作成したイメージを使用する人はだれでも、何にでもアクセスできますADD。Dockerはレイヤーで機能し、レイヤーADDは画像の一部として存在するため、後で削除しても同じです。明確にするために、あなたADDはビルド時にのみ何かADDを実行時に決してすることはできません。

使用したい場合のいくつかの例ADD

  • Dockerfileに参照およびインストールする必要がある要件がいくつか、requirements.txtファイルにあります。その後、行うことができますADD ./requirements.txt /requirements.txtが続きますRUN pip install -r /requirements.txt
  • たとえば、アプリのコードをDockerfileのコンテキストとして使用したい場合、たとえば、アプリディレクトリをイメージの作業ディレクトリとして設定し、コンテナ内のデフォルトのコマンドをイメージから実行して、実際にアプリを実行したい場合は、できる:

    ADD ./ /usr/local/git/my_app

    WORKDIR /usr/local/git/my_app

    CMD python ./main.py

ボリューム

一方、ボリュームは、イメージから実行されるコンテナーに、コンテナーが実行されているローカルマシン上のパスにアクセスできるようにするだけです。Dockerfileでディレクトリのファイルを使用するVOLUMEことはできません。あなたのボリュームのディレクトリにあるものはすべてしますビルド時にアクセスできませんが、実行時にアクセスできるようになります

使用したい場合のいくつかの例VOLUME

  • コンテナで実行されているアプリはログを作成し/var/log/my_appます。これらのログは、ホストマシンでアクセス可能であり、コンテナが削除されたときに削除されないようにする必要があります。これを行うには、Dockerfileにを/var/log/my_app追加VOLUME /var/log/my_appしてマウントポイントを作成し、コンテナを実行します。docker run -v /host/log/dir/my_app:/var/log/my_app some_repo/some_image:some_tag
  • コンテナー内のアプリがアクセスできるようにするローカル設定ファイルがいくつかあります。おそらく、これらの設定ファイルは、ローカルマシンとdevと本番では異なります。特に、これらの設定ファイルが秘密になっている場合は、イメージに含めたくないでしょう。その場合の適切な戦略はVOLUME /etc/settings/my_app_settings、Dockerfile に追加し、コンテナをで実行docker run -v /host/settings/dir:/etc/settings/my_app_settings some_repo/some_image:some_tagし、/ host / settings / dirがアプリの実行が予想されるすべての環境に存在することを確認することです。

13
ADDとVOLUMEでこれまでに見つけた中で最も有用な投稿
Jasmeet

5
VOLUMEが指定されていて、Dockerの実行中に提供されなかった場合(たとえば、-v xxxパラメーターが欠落している場合)はどうなりますか?担当者です。その後、ボリュームは実質的に一時的になりますか?
col.panic

Dockerfile内では、ボリュームはおそらく永続化やデバッグのみを目的としていますが、volumeコマンドラインスイッチを使用して、アプリを既存のイメージに入れ(Dockerfileは不要)、このように実行できdocker run -v $HOST_PATH:$CONTAINER_PATH node:latest node $CONTAINER_PATH/app.jsます。
Chinoto Vokro

素敵な「レイヤー」ディテール
ストラトバリウス

27

このVOLUME命令により、実行時にDockerコンテナーにデータボリュームが作成されます。の引数として提供されるVOLUMEディレクトリは、ユニオンファイルシステムをバイパスするディレクトリであり、主に永続データと共有データに使用されます。

を実行docker inspect <your-container>すると、Mountsセクションの下Sourceに、ホスト上のディレクトリの場所Destinationを表すと、コンテナ内のマウントされたディレクトリの場所を表すが表示されます。例えば、

"Mounts": [
  {
    "Name": "fac362...80535",
    "Source": "/var/lib/docker/volumes/fac362...80535/_data",
    "Destination": "/webapp",
    "Driver": "local",
    "Mode": "",
    "RW": true,
    "Propagation": ""
  }
]

以下が3つの使用例ですdocker run -v

  1. docker run -v /data:これはVOLUME、Dockerfileで命令を指定することに似ています。
  2. docker run -v $host_path:$container_path:これにより、実行時に$host_pathホストから$container_pathコンテナーにマウントできます。開発中、これはホスト上のソースコードをコンテナと共有するのに役立ちます。本番環境では、これを使用して、ホストのDNS情報(にある/etc/resolv.conf)やシークレットなどをコンテナーにマウントできます。逆に、この手法を使用して、コンテナーのログをホスト上の特定のフォルダーに書き込むこともできます。両方$host_path$container_path絶対パスでなければなりません。
  3. docker run -v my_volume:$container_path:これにより、コンテナにデータボリュームが作成され$container_path、名前が付けられmy_volumeます。これは、を使用してボリュームを作成して名前を付けるのと基本的に同じdocker volume create my_volumeです。このようなボリュームの名前は、Flockerなどのマルチホストストレージドライバーを使用するコンテナーデータボリュームと共有ストレージボリュームに役立ちます。

ホストフォルダーをデータボリュームとしてマウントする方法は、Dockerfileでは使用できないことに注意してください。ドッカーのドキュメントを引用するには、

注:移植性と共有目的のため、Dockerfileからは使用できません。ホストディレクトリはその性質上、ホストに依存しているため、Dockerfileで指定されたホストディレクトリは、すべてのホストで機能するとは限りません。

ここで、開発以外の環境でファイルをコンテナーにコピーする場合は、DockerfileのADDor COPY命令を使用できます。これらは、開発以外のデプロイメントに通常使用するものです。


3
2つのDockerファイルを作成する必要がありますか?1つは開発用、もう1つはデプロイメント用ですか?
クリスティアンガルシア

そうは思いません。コマンドADDによってのみ実行されるので、Dockerfileに命令があることには何の問題もありませんdocker build。これは、他の人が初めてコンテナーをビルドするとき、および他の非開発環境にコンテナーをデプロイする準備ができているときに必要です。
ivan.sim

3
しかし、ファイルなしでイメージをビルドし、-v開発用のコマンドを使用し、別のDockerファイルADDでデプロイメント用のファイルを含むイメージを作成する方が効率的ではないでしょうか?
クリスティアンガルシア

1
それはあなたが決めなければならないトレードオフです。自分に合ったものを選んでください。ADDとにかくビルドはどれくらいかかりますか?合計で数秒ですか?2つのDockerfileファイルがあり、それを他のユーザーと共有する(またはdocker レジストリで公開する)場合、どちらがデフォルトですか?適切なデフォルトのDockerfileが適切なユーザーに確実に届くように、追加のメンテナンスオーバーヘッドが発生します。しかし、結局のところ、自分に最適なものを決定します。個人的には、コンテナーを構築するためのDockerfileが1つだけであることを確認したいと思っています。
ivan.sim 2015年

11
ちなみに、最初にADDを作成してから、開発用に-vでそのaddをオーバーライドしても問題ないと思います。そうすれば、個別のDockerfileは必要ありません。
Attila Szeremi 2015年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.