先ごろの記事で、Docker エンジニアの Stephen Turner 氏が、開発者が Docker コンテナとローカルホスト間のファイル共有とOS間でパフォーマンスにどのような違いがあるかを理解するのに役立ついくつかのベストプラクティスを共有した。
Docker Desktop は、ローカルファイルシステムの一部をコンテナと共有するための2つのメカニズムを提供している。つまり、バインドマウントと名前付きボリュームだ。さらに、ファイルシステムの一部をコンテナ自体のファイルシステム内にコピーできる。
それぞれのアプローチは、ローカルファイルシステムとコンテナ (および別々のコンテナ間) でファイルを共有するという同じ目標を果たしている。ただし、それぞれのメカニズムに長所と短所のバランスがあり、異なるユースケースに適している。
ファイルのコンテナへのコピーには大きな欠点がある。コンテナを削除すると、ファイルへの変更を含め、コピーされたすべてのデータが失われる。編集する必要のあるコードを共有したい場合、これは間違いなく望ましい結果ではない。
Turner 氏が説明するように、他の2つのオプションに関しては、バインドマウントが最も柔軟なソリューションだが、それらのパフォーマンスは共有ボリュームより劣っている。
[...] 仮想化の性質上、ホストとVMの境界を越える際に避けられない小さなオーバーヘッドが常に存在します。非常に小さいですが、巨大なソースツリーと多数の読み取りと書き込みがある開発環境では、それが積み上がり、パフォーマンスに目に見える影響を与えることがあります。
それは、macOS と Windows マシンで Docker を実行する場合のみに発生する問題であることに注意が必要だ。Linux はバインドマウントされたファイルシステムに直接アクセスできる。
これに基づいて、Turner 氏は、バインドマウントまたは共有ボリュームをいつ使用すれば良いかを理解するためのいくつかの基準を提案している。
バインドマウントは、編集する必要のあるコードを共有したい場合に最適な方法だ。ただし、多数の読み取り/書き込み操作を実行する必要がある非常に大規模なリポジトリでは問題になる可能性がある。このような場合、Mutagen や docker-sync などのサードパーティソリューションを使用してミラーリングを試すことができる。
一方、バインドマウントは、データベース、依存関係ツリーやライブラリ、キャッシュ、ログファイルなどには適していない。これら全ての場合共有ボリュームを使用した方がよいだろう。
この状況は変わる可能性があると Turner 氏は語っている。ホストとVMとの間でファイルを共有するために特別に設計された Virtiofs によってだ。Virtiofs は、macOS の Docker Desktop プレビューですでに利用可能になっている。
Turner 氏の記事には、ここで要約したものをはるかに超える詳細が含まれている。興味がある場合は見逃さないでください。