バインド マウント の使用¶
ファイルやディレクトリは Docker ホスト上にあらかじめ存在している必要はありません。存在しなければ、必要に応じて作成されます。バインド マウントは高性能ですが、ホストマシンのファイルシステムで利用可能な、特定のディレクトリ構造に依存します。新しい Docker アプリケーションを開発する場合は、代わりに 名前付きボリューム の利用を検討してください。バインド マウントは Docker CLI コマンドを使って直接管理できません。
-v と --mount フラグの選択¶
一般的に、 --mount は説明的かつ冗長です。最大の違いは、 -v 構文は1つのフィールドに全てのオプションをつなげるのに対し、 --mount 構文はそれらを分けます。以下は各フラグの比較です。
ちなみに
新しいユーザは --mount 構文を使うべきです。経験のあるユーザは -v や --volume 構文に慣れているでしょうが、調査によって、より簡単に利用できると分かっている --mount の利用を推奨します。
-vか--volume:コロン記号(:)で区切られた、3つのフィールドで構成。フィールドは正しい順番で記述する必要があり、それぞれのフィールドの意味は直ちに分からないバインドマウントの場合、1つめのフィールドは ホストマシン 上のファイルやディレクトリのパス。
2つめのフィールドは、コンテナ内にマウントされるファイルやディレクトリがどこにあるかのパス。
3つめのフィールドはオプションで、
ro、z、Zのようなオプションをカンマで区切ったリスト。これらオプションについては、後ほど扱う。
--mount:複数のキーバリューのペアで構成。それらは、カンマで区切られ、かつ、それぞれが<key>=<value>のセットで構成。--mount構文は-vや--volumeよりも冗長だが、キーの順番は意味が無く、フラグの値は理解しやすい。マウントの
type(形式)は、bind、volume、tmpfsのどれか。このトピックで扱うのはバインド マウントのため、形式は常にbind。マウントの
source(マウント元)。バインド マウントでは、これが Docker デーモン ホスト上のファイルやディレクトリのパスになる。sourceもしくはsrcとして指定。destination(マウント先)の値は、コンテナ内にマウントされるファイルやディレクトリのパスがどこかを示す。destination、dst、targetのどれかを指定。readonly(読み込み専用)オプションがあれば、バインド マウントは 読み込み専用としてコンテナ内にマウント される。
bind-propagationオプションがあれば、 bind propagation (バインド伝搬) を変更。rpriavte、private、rshared、shared、rslave、slaveのどれか。 *--mountフラグは selinux ラベルを変更する-zと-Zオプションをサポートしない。
以降の例では --mount と -v 構文の両方を可能であれば表し、かつ、 --mount を先に表します。
-v と --mount との挙動の違い¶
-v と --volume フラグは長い間 Docker の一部のため、これらの挙動は変更できません。これが意味するのは、 「-v」と「--mount」間では、各々の挙動が異なります 。
-v や --volume をバインド マウントに使う時、Docker ホスト上にファイルやディレクトリが存在しなければ、 -v はエンドポイントを作成します。 常にディレクトリとして作成されます 。
--mount をバインド マウントに使う時、Docker ホスト上にファイルやディレクトリが存在しなければ、 Docker は自動的に作成**しません** し、エラーを起こします。
バインドマウントを使ってコンテナを起動¶
source ディレクトリがあると想定します。ここをソースコードの構築時に使いますが、アーティファクト(構築結果)は他のディレクトリ source/target/ に保存します。アーティファクトをコンテナの /app/ で使いたい場合や、コンテナが新しく構築するたびに、開発ホスト上のバインド元へとアクセスしたい場合があるでしょう。以下のコマンドを使い、 target/ ディレクトリをコンテナの /app/ にバインドマウントします。そして source ディレクトリの中でコマンドを実行します。 $(pwd) サブコマンドは、Linux や macOS ホスト上での、現在の作業ディレクトリを展開します。Windows の場合は、 Windows 上でのパス変換 をご覧ください。
以下の -v と --mount 例は、どちらも同じ結果になります。一度実行すると、 devtest コンテナを削除しないと、両方実行できません。
--mount$ docker run -d \ -it \ --name devtest \ --mount type=bind,source="$(pwd)"/target,target=/app \ nginx:latest
-v$ docker run -d \ -it \ --name devtest \ -v "$(pwd)"/target:/app \ nginx:latest
docker inspect devtest を使い、バインドマウントが正しく作成されているのを確認します。 Mounts セクションを見ます。
"Mounts": [
{
"Type": "bind",
"Source": "/tmp/source/target",
"Destination": "/app",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],
この表示は、マウントしているのはバインド マウントであり、正しいマウント元(Source)とマウント先(Destination)が指定され、かつ、マウントは読み書きでき、さらにプロパゲーションは rprivate に設定されています。
コンテナを停止します。
$ docker container stop devtest
$ docker container rm devtest
コンテナ上の空ではないディレクトリにマウント¶
コンテナ上の
以下は外部から扱う例ですが、コンテナの /usr/ ディレクトリの内容は、ホストマシン上の /tmp/ ディレクトリに置き換えられます。多くの場合、非機能的なコンテナに結果としてなります。
--mount と -v の例は、どちらも同じ結果になります。
--mount$ docker run -d \ -it \ --name broken-container \ --mount type=bind,source=/tmp,target=/usr \ nginx:latest docker: Error response from daemon: oci runtime error: container_linux.go:262: starting container process caused "exec: \"nginx\": executable file not found in $PATH".
--v$ docker run -d \ -it \ --name broken-container \ -v /tmp:/usr \ nginx:latest docker: Error response from daemon: oci runtime error: container_linux.go:262: starting container process caused "exec: \"nginx\": executable file not found in $PATH".
)コンテナは作成されますが、開始できません(訳者注:見ての通り、実行してもエラーが出ます)。削除します。
$ docker container rm broken-container
読み込み専用のバインドマウントを使用¶
アプリケーション開発では、コンテナがバインド マウントへの書き込みを必要とするなら、変更は Docker ホスト側へと反映されます。一方で、コンテナがデータの読み込みだけを必要とする場合があります。
以下は前述の例を変更したもので、コンテナ内へのマウントポイントの後に、 ro をオプションのリスト(デフォルトは空)に追加し、ディレクトリを
例にある --mount と -v は、どちらも同じ結果になります。
--mount$ docker run -d \ -it \ --name devtest \ --mount type=bind,source="$(pwd)"/target,target=/app,readonly \ nginx:latest
-v$ docker run -d \ -it \ --name devtest \ -v "$(pwd)"/target:/app:ro \ nginx:latest
読み込み専用のバインドマウントが正しく作成されたかどうかを確認するには、 docker inspect nginxtest を使います。 Mounts セクションを探します。
"Mounts": [
{
"Type": "bind",
"Source": "/tmp/source/target",
"Destination": "/app",
"Mode": "ro",
"RW": false,
"Propagation": "rprivate"
}
],
コンテナを停止します。
$ docker container stop devtest
$ docker container rm devtest
バインド プロパゲーションの設定¶
rprivate がデフォルトです。Linux ホスト マシン上のバインド マウントのみ設定変更が可能です。バインド プロパゲーションは高度なトピックであり、多くのユーザは変更の必要がほとんどないでしょう。
指定したバインドマウントや名前付きボリューム内で作成されたマウントを、そのマウントの複製に /mnt は /tmp もマウントしていると仮定します。 /tmp/a をマウントしている場所の /mnt/a にも有効です。それぞれの伝搬設定は、再帰的に補完されます。再帰的な例として、 /tmp/a が /foo にもマウントしていると仮定します。伝搬設定の制御は、 /mnt/a と /tmp/a にも及びます。
警告
マウント 伝搬は Docker Desktop では機能しません。
伝搬設定 |
説明 |
|---|---|
|
オリジナルマウントのサブマウントは、 |
|
|
|
マウントは |
|
共有マウントと同じですが、マウントポイントをネストして、あらゆるオリジナルもしくは複製されたマウントポイントまで、伝搬が広がります。 |
|
slave と同じですが、マウントポイントをネストして、あらゆるオリジナルもしくは複製されたマウントポイントまで、伝搬が広がります。 |
|
デフォルトです。プライベートと同じであり、あらゆるオリジナルもしくは複製されたマウントポイントから、他の場所に現れないのを意味します。 |
マウントポイントにバインド伝搬を設定する前に、ホストファイルシステムで既にバインド伝搬をサポートしている必要があります。
バインド伝搬についての詳しい情報は、 shared subtree に関する Linux Kernel ドキュメント をご覧ください。
以下の例は target/ ディレクトリをコンテナ内に2度マウントし、2つめのマウントに ro オプションをつけ、さらに rslave バインド伝搬オプションを付けます。
--mount と -v 例は、どちらも同じ結果になります。
--mount$ docker run -d \ -it \ --name devtest \ --mount type=bind,source="$(pwd)"/target,target=/app \ --mount type=bind,source="$(pwd)"/target,target=/app2,readonly,bind-propagation=rslave \ nginx:latest
-v$ docker run -d \ -it \ --name devtest \ -v "$(pwd)"/target:/app \ -v "$(pwd)"/target:/app2:ro,rslave \ nginx:latest
これで /app/foo を作成し、 /app/foo/ も存在します。
selinux ラベルを設定¶
selinux を使う時、コンテナ内にマウントされている ホストファイルやディレクトリ の selinux ラベルを、 z か Z オプションを追加して変更できます。これはホストマシン上自身のファイルやディレクトリにも影響し、結果的に Docker の範囲外となります。
zオプションは、バインドマウントの内容が、複数のコンテナ間で共有されるのを示すZオプションは、バインドマウントの内容が、プライベートかつ非共有を示す
これらのオプションは極度に注意して使います。 /home/ や /usr/ のようなシステムディレクトリを Z オプションでバインドマウントすると、ホストマシンが操作不可能な状況になり、手動でホストマシン上のファイルを
重要
サービスでバインドマウントを使う場合、 selinux ラベル( :Z と :z )だけでなく、 :ro も無視されます。詳細は moby/moby #32579 をご覧ください。
以下の例は z オプションを設定し、バインドマウントの内容を、複数のコンテナが共有できるように設定します。
--mount フラグを使う場合は、 selinux のラベルを変更できません。
$ docker run -d \
-it \
--name devtest \
-v "$(pwd)"/target:/app:z \
nginx:latest
compose でバインドマウントを使用¶
バインドマウンドを使う1つの Docker Compose サービスは、このようにします。
version: "3.9"
services:
frontend:
image: node:lts
volumes:
- type: bind
source: ./static
target: /opt/app/staticvolumes:
myapp:
compose で bind 型のボリュームを使うための詳しい情報は、
volumes の Compose リファレンス と、 ボリューム設定の Compose リファレンス をご覧ください。
次のステップ¶
ボリューム について学ぶ
tmpfs マウント について学ぶ
ストレージ ドライバ について学ぶ
参考
- Use bind mounts