ホストディレクトリアクセスのためのDocker Bind Mount

bind mountを使用してホストディレクトリをDocker containerにマウントする方法を学びます。構文、セキュリティへの影響、開発中のライブコードリロードなどの一般的なユースケースについて解説します。

Volumes & Storage

詳細な説明

ホストとContainerのファイルシステムを橋渡しする

Bind mountはホストマシン上の特定のディレクトリ(またはファイル)をcontainer内に直接マッピングします。名前付きvolumeとは異なり、bind mountでは正確なホストパスを完全に制御できます:

docker run -d -v /home/user/project:/app -p 3000:3000 node:20

これによりホストのディレクトリ/home/user/projectがcontainer内の/appにマウントされます。ホスト上のファイル変更はcontainer内ですぐに反映され、その逆も同様です。

Bind Mountの構文

# 絶対ホストパス(bind mountには必須)
-v /absolute/host/path:/container/path

# $(pwd)を使用して現在のディレクトリを指定
-v $(pwd):/app

# 読み取り専用bind mount(containerはホストファイルを変更不可)
-v $(pwd)/config:/app/config:ro

# --mountを使用(より明示的、推奨)
--mount type=bind,source=/host/path,target=/container/path

開発ワークフロー:ライブコードリロード

bind mountの最も一般的な用途はライブ開発です。ソースコードをcontainerにマウントすることで、ホスト上のコード変更がcontainer内でホットリロードをトリガーします:

docker run -d \
  --name dev-server \
  -v $(pwd)/src:/app/src \
  -v $(pwd)/public:/app/public \
  -p 3000:3000 \
  my-dev-image

container内のファイルウォッチャー(Nodemon、Vite、webpack dev server)があれば、ホストでファイルを保存すると即座にリビルドがトリガーされます。

Bind Mountと名前付きVolumeの違い

重要な違い:bind mountはcontainerディレクトリをホストの内容で上書きします。container imageの/appにファイルがある場合、bind mountはそれらを完全にホストディレクトリの内容で置き換えます。

# 名前付きvolume:imageの内容を事前に反映
docker run -v mydata:/app/data my-image  # /app/dataにimageファイルあり

# Bind mount:ホストの内容で置き換え(空の場合もあり!)
docker run -v $(pwd)/data:/app/data my-image  # /app/dataにホストファイルのみ

Bind Mountでのnode_modulesの処理

Node.js開発での一般的な問題:プロジェクトディレクトリ全体をbind mountすると、containerのnode_modulesが上書きされます:

docker run -d \
  -v $(pwd):/app \
  -v /app/node_modules \
  node:20 npm start

/app/node_modulesの匿名volumeがcontainerのインストール済み依存関係を保持し、ホストの(互換性がない可能性のある)node_modulesによる上書きを防ぎます。

セキュリティに関する考慮事項

  • Bind mountはホストのファイルシステムパスをcontainerに公開します。侵害されたcontainerがホストの機密ファイルを読み取りまたは変更する可能性があります。
  • containerが書き込みアクセスを必要としない場合は、:ro(読み取り専用)を使用してください。
  • 絶対に必要でない限り、/etc/var$HOMEなどの機密ディレクトリのマウントは避けてください。
  • 本番環境では、セキュリティとポータビリティのためにbind mountよりも名前付きvolumeを優先してください。

ファイル所有権とパーミッション

containerは多くの場合root(UID 0)で実行されますが、ホストユーザーは異なるUIDを持っている場合があります。bind mount内でcontainerが作成したファイルはホスト上でrootが所有者になる可能性があります:

# ホストの所有権に一致するよう現在のユーザーでcontainerを実行
docker run -v $(pwd):/app --user $(id -u):$(id -g) my-image

ユースケース

ホストマシン上のソースコード変更がDocker container内に即座に反映されるローカル開発環境をセットアップし、imageを再ビルドせずにホットリロードを実現する場合に使用します。

試してみる — Docker Run Command Builder

フルツールを開く