Dock Stay
データの置き場を選ぶ - volume / bind mount の使い方・オプション・サンプル

データの置き場を選ぶ - volume / bind mount

volume は Docker が管理する永続領域、bind mount はホストの任意パスをそのまま見せる機能。UID/GID ズレや SELinux ラベルが原因で「書き込めない」エラーが起きがちなので、対処パターンを押さえる。

概念図

volume / bind mount diagram

構文

bash
docker run -v <name>:/path-in-container <image>           # named volume
docker run -v /host/path:/path-in-container[:ro|:z|:Z] <image>   # bind mount

実例

名前付き volume を作って DB データを永続化

bash
docker volume create pgdata
docker run -d --name db \
  -v pgdata:/var/lib/postgresql/data \
  postgres:16

bind mount + 現在ユーザー UID + SELinux ラベル付与

bash
docker run --rm \
  -u "$(id -u):$(id -g)" \
  -v "$PWD":/work:Z \
  -w /work \
  node:22 npm test

volume の立ち位置

Docker の volume は、コンテナのライフサイクルから独立した永続領域を Docker 自身が管理する仕組み。

実体は Linux では /var/lib/docker/volumes/<name>/_data に置かれ、Docker Desktop では VM 内に格納される。

ユーザーはホスト側の具体的なパスを意識せず、pgdata:/var/lib/postgresql/data のような名前でマウントするだけで良い。

docker volume lsdocker volume inspect で一覧・詳細を確認でき、バックアップは一時コンテナを立てて tar で吸い出すのが定番になる。

DB や Redis のデータのように「ホストのファイルシステムの構造に依存させたくない永続データ」は volume が第一選択になり、ホストユーザーの UID/GID 問題も起きにくい。

bind mount の UID/GID ズレ問題

bind mount はホストの任意のパスをそのままコンテナに見せるため、「開発中にソースコードを編集して即反映」といった用途に向いている。

ただしコンテナ内のプロセスが root(UID 0)や独自の非 root ユーザーで動いていると、作成されたファイルの所有者がホストのユーザーと合わず、「ホスト側で編集できない」「ビルドが upload 権限で失敗する」などの問題が起きる。

対策は docker run -u "$(id -u):$(id -g)" で現在のユーザー UID をコンテナに渡すか、Dockerfile で USER を指定してユーザーを固定するか、chown しておくか、の 3 通りが基本になる。

Windows 上の Docker Desktop では NTFS と Linux ファイルシステムの差で chmod が反映されない点もセットで覚えておく。

`:z` / `:Z` (SELinux) と `:ro`

RHEL / Fedora / Rocky Linux など SELinux が enforcing のディストリでは、bind mount 時にラベルが合わず「Permission denied」で弾かれることがある。

オプションの :z(小文字)は「このパスは複数コンテナで共有してよい」というラベルを付け、:Z(大文字)は「このコンテナ専用」のプライベートラベルを付ける。

ホスト側の共有ディレクトリに :Z を付けるとホスト上の他プロセスからアクセスできなくなる場合があるため、用途によって使い分ける。

読み取り専用マウントは :ro を末尾に付けるだけで、設定ファイルや SSL 証明書など「コンテナからは書き換えてほしくないデータ」に有効。

複数指定は :ro,Z のようにカンマで連結する。

bash
# SELinux 有効ホストで共有ラベルを付与 / shared label under SELinux
docker run -v /srv/data:/data:z myimage

# コンテナ専用ラベル + 読み取り専用 / private label + read only
docker run -v /etc/ssl/certs:/certs:ro,Z myimage

関連トピック