Docker開発において、あまり把握せずやり過ごしてしまうものの1つに「ファイル共有」があります。
自分がその一人なのですが、yarn install
が遅かったことをキッカケに調べてみました。
タイトル通り、まんべんなく解説する記事ではなく、「ここは押さえておいたほうがいい」と感じたものをピックアップします。
より詳細に知りたい方は、下記を読んでください。本記事の引用元もこれです。
Docker におけるデータ管理 | Docker ドキュメント
もし誤りがあれば教えてください!
要約
- ファイル共有の方法が2つ(本当は3つ)あることを知ろう
- volumes
- bind mounts
- (tmpfs mounts) ※この記事では割愛します
-
--volumes
オプションと--mount
オプションは、それぞれtypeのvolumesとbind mountsと関連している訳ではないので初心者は注意 - bind mountsではなくvolumesでボリューム共有されるようなコマンド、設定ファイルを書けるようになろう
-
--volumes
オプションでなく、--mount
オプションを使おう -
docker-compose.yml
のvolumes
の正式な書き方を覚えよう
-
ファイル共有の方式
Docker コンテナーにおけるファイルをホストマシン上に保存する方法は 2 つあります。 これを行えば、コンテナーが停止した後にもデータを維持していくことができます。 その 2 つの方法とは ボリューム(volumes) と バインドマウント(bind mounts) です。
まずは、ファイル共有の方法にvolumesとbind mountsがあることを知りましょう。
このタイミングでは、「volumesとは」「bind mountsとは」という話は省略して、この2つがあることを理解しておけばOKです。
なぜかというと、volumesで管理できる方法を覚えておけばいいからです。
ボリュームは Docker においてデータを維持するための最良の方法です。
そのため2つの違いを知るよりも、まずはdocker run
やdocker-compose.yml
で指定しているファイル共有の方式を確認できるようになりましょう。
【初心者向け】volumesとmountのオプションを混同しないように
Dockerを始めたばかりの方の中には、次のように考える人もいるでしょう。
-
docker run --volumes
と指定していたら、ファイル共有の方式はvolumes -
docker run --mount
と指定していたら、ファイル共有の方式はbind mounts
上記は間違いです。オプションの名前とファイル共有方式に関連はありません。
また2021年現在では、--volumes
オプションより--mount
オプションを利用するほうが良いこともお伝えします。
はじめて利用する方は
--mount
を利用してください。 上級ユーザーは-v
や--volume
を用いることに慣れているかもしれませんが、--mount
を利用するように心がけてください。--mount
の方が簡単に利用することができるとの調査もあります。
ファイル共有方式をvolumesにする方法
ではどうすればvolumesでファイル共有ができるのか。
シンプルな回答は、「Dockerボリュームで共有すること」です。
よく使われるであろうdocker run
とdocker-compose.yml
の場合で説明します。
docker run
docker run --mount
では、次の設定ができます。
-
type: ここで'volumes'または'bind mounts'を指定できる
- bind, volume, tmpfsから選ぶ
- source: ホスト側のディレクトリまたはDockerボリューム
- ここでDockerボリュームを指定すればOK
- target: コンテナ側のディレクトリ
上記の通りですので、sample-volumes
というDockerのボリュームを作成して、これを共有したコンテナdevtest
を作ってみます。
$ docker volume create sample-volumes
$ docker run -d \
--name devtest \
--mount source=sample-volumes,target=/app \
ubuntu
このように書くことで、Dockerボリュームでファイル共有ができました。
docker inspect
コマンドで、実際にそのようになっていることも確認可能です。
$ docker inspect devtest
ちなみにbind mountsになるときは、sourceに実際のディレクトリを指定した場合です。 ex.) docker run --mount src:/app/arc
なんとなくDockerコンテナを立ち上げている場合は、たいていbind mountsになっていることでしょう。
docker-compose.yml
同じくdocker-compose.yml
も確認します。
下記のリファレンスにあるように、docker-compose.yml
のvolumes
の書き方は、shortとlongの2種類があります。
Compose file version 3 reference | Docker Documentation
どちらでも書けるようになるといいですが、先にlongを理解したほうがいいので、こちらを紹介します。なぜかというと、前述の--mount
オプションと同じだからです。
同様に、sample-volumes
というDockerのボリュームを共有したサービスdevtest
を作ってみます。
version: "3.9"
services:
devtest:
image: ubuntu
volumes:
- type: volume
source: sample-volumes
target: /app
volumes:
sample-volumes:
末尾のvolumes
でDockerボリュームを作り、これをsource
に指定する。target
やtype
はdocker run
と同じです。
なおbind mountsになっている場合も、docker run
とほぼ同じです。一応、サンプルのYAMLを貼っておきます。
version: "3.9"
services:
web:
image: ubuntu
volumes:
- type: bind
source: src
target: /app/src
# 上と同じ内容を、1行のshortで書くと次の通り
- "src:/app/arc"
おわりに
おめでとうございます!
これでDockerのファイル共有がbind mountsかvolumesかを判別でき、さらに形式をvolumesへ変更できました。執筆者と完全に同じレベルです。
ここまで理解できたら、volumesそしてbind mountsの使い分けを勉強しても苦ではなくなるでしょう。
最初に挙げた参考ページの、「ボリュームの適切な利用例」、「バインドマウントの適切な利用例」を確認してみてください。