Dockerのデータ永続化、2つの方法を正しく使い分けよう
Dockerコンテナは、停止・削除するとコンテナ内のデータも一緒に消えてしまいます。これを防ぐために「データの永続化」が必要ですが、その方法には大きく分けて Volume(ボリューム) と bind mount(バインドマウント) の2つがあります。
この記事では、両者の仕組み・使い方・パフォーマンスの違いを比較しながら、どう使い分ければよいかを解説します。
結論:本番はVolume、開発はbind mount
先に結論をお伝えします。
- 本番環境・データ保存 → Volume(Dockerが管理し、安全で高パフォーマンス)
- 開発環境・ソースコード同期 → bind mount(ホスト側の変更が即座にコンテナに反映される)
以下で、それぞれの特徴を詳しく見ていきましょう。
Volume と bind mount の比較表
| 項目 | Volume | bind mount |
|---|---|---|
| 保存場所 | Dockerが管理する領域(/var/lib/docker/volumes/) |
ホストマシンの任意のパス |
docker run -v の指定 |
-v ボリューム名:コンテナパス |
-v /ホストパス:コンテナパス |
--mount の指定 |
--mount type=volume,source=vol,target=/app |
--mount type=bind,source=/host,target=/app |
| Docker CLIでの管理 | docker volume ls / inspect で管理可能 |
管理コマンドなし(ホスト側で直接操作) |
| パフォーマンス(Linux) | ほぼ同じ | ほぼ同じ |
| パフォーマンス(Mac/Windows) | ✅ 高速 | VM経由のファイル共有で遅い |
| バックアップ | docker volume コマンドや tar で容易 | ホスト側の通常のバックアップ手段で対応 |
| セキュリティ | ✅ Dockerが管理し、ホストへの影響が限定的 | ホストの任意パスにアクセスできるためリスクが高い |
💡 Mac/WindowsでVolumeが速い理由
Mac/WindowsのDockerは内部的にLinux VMを動かしています。bind mountの場合、ホストOS ↔ VM間のファイル共有が発生するためオーバーヘッドが生じます。一方、VolumeはVM内のLinuxファイルシステムに直接保存されるため高速です。
Volume の使い方
ボリュームを作成する
# ボリュームを作成
docker volume create my-data
# ボリューム一覧を確認
docker volume ls
# ボリュームの詳細を確認
docker volume inspect my-data
docker volume inspect を実行すると、保存先のパス(/var/lib/docker/volumes/my-data/_data)などの情報が確認できます。
コンテナでVolumeを使う
# -v でボリュームをマウントして起動
docker run -d -v my-data:/app/data nginx
# ボリュームが存在しない場合は自動作成される
docker run -d -v new-volume:/app/data nginx
💡 ボリュームの自動作成
-v で指定したボリューム名が存在しない場合、Dockerが自動で作成してくれます。ただし、意図しない名前のボリュームが増えないよう、事前に docker volume create で作成しておくのがおすすめです。
ボリュームの削除
# 特定のボリュームを削除
docker volume rm my-data
# 使われていないボリュームを一括削除
docker volume prune
⚠️ データの消失に注意
docker volume rm や docker volume prune を実行すると、ボリューム内のデータは完全に削除されます。本番環境で使用する場合は、事前にバックアップを取ってください。
bind mount の使い方
bind mountは、ホスト側の任意のディレクトリをコンテナ内のパスにマウントします。ボリューム名ではなくホスト側の絶対パスを指定するのが特徴です。
# ホストのカレントディレクトリをコンテナにマウント
docker run -d -v $(pwd)/src:/app/src nginx
# 読み取り専用でマウント(:ro を付ける)
docker run -d -v $(pwd)/config:/app/config:ro nginx
開発時にソースコードをbind mountすると、エディタで保存した変更がコンテナ内にリアルタイムで反映されます。ホットリロード対応のフレームワークと組み合わせると、非常に効率的な開発環境を構築できます。
⚠️ 存在しないパスの指定に注意
bind mountでホスト側に存在しないパスを指定した場合、Dockerが自動でディレクトリを作成します。意図しない空ディレクトリがマウントされ、コンテナ内のファイルが見えなくなるケースがあるので注意してください。
-v と –mount の書き方の違い
Dockerでは、マウントの指定に -v(--volume)と --mount の2つの構文が使えます。
-v(–volume)構文
# Volume
docker run -d -v my-data:/app/data nginx
# bind mount
docker run -d -v /home/user/src:/app/src nginx
-v はコロン区切りで短く書ける反面、Volumeとbind mountの見分けがつきにくいという欠点があります。先頭が / や ./ で始まればbind mount、そうでなければVolumeと解釈されます。
–mount 構文
# Volume
docker run -d --mount type=volume,source=my-data,target=/app/data nginx
# bind mount
docker run -d --mount type=bind,source=/home/user/src,target=/app/src nginx
# 読み取り専用
docker run -d --mount type=bind,source=/home/user/config,target=/app/config,readonly nginx
--mount は type を明示するため、何をマウントしているかが一目でわかります。Docker公式ドキュメントでも --mount 構文が推奨されています。
| 比較項目 | -v |
--mount |
|---|---|---|
| 書き方 | コロン区切りで短い | キー=値の形式で長い |
| type の明示 | なし(パスの書き方で判別) | あり(type=volume / type=bind) |
| 存在しないパスの挙動 | 自動で作成される | bind mountの場合はエラーになる |
| 公式の推奨 | – | ✅ 推奨 |
💡 初心者には –mount がおすすめ
--mount は記述が長くなりますが、タイプミスや意図しない挙動を防ぎやすいため、慣れないうちは --mount を使うのがおすすめです。特にbind mountで存在しないパスを指定したときにエラーになるのは、トラブルの早期発見に役立ちます。
使い分けの判断フロー
どちらを使うか迷ったときは、以下の流れで判断してみてください。
- データベースやアプリのデータを保存したい → Volume
- 開発中のソースコードをコンテナと同期したい → bind mount
- 設定ファイルだけをコンテナに渡したい → bind mount(読み取り専用)
- Mac/Windowsで大量ファイルのI/Oが必要 → Volume(パフォーマンスのため)
- Docker Composeで複数コンテナ間のデータ共有 → Volume(名前付きボリューム)
- CI/CDパイプラインでのビルドキャッシュ → Volume
基本的には「Dockerに管理を任せたいならVolume、ホスト側のファイルをそのまま使いたいならbind mount」と覚えておけば大丈夫です。
💡 tmpfsマウントについて
Docker にはもう一つ tmpfs マウントがあり、ホストのメモリ上にデータを保存します。一時的なキャッシュやセキュリティ上ディスクに書きたくないデータに使われますが、コンテナ停止で消えるため、永続化の手段としては使われません。
まとめ
Dockerのデータ永続化における Volume と bind mount の違いを整理しました。
- Volume:Dockerが
/var/lib/docker/volumes/以下で管理。docker volumeコマンドで操作でき、本番環境に適している - bind mount:ホストの任意ディレクトリをマウント。開発時のソースコード同期に便利
- 構文:
-vは手軽だが、--mountの方が明示的で公式推奨 - パフォーマンス:Mac/WindowsではVolumeの方が高速
迷ったら Volume を選ぶのが安全 です。開発中にホストのファイルを同期したい場面だけ bind mount を使いましょう。
Dockerの基本的なコマンド操作についてはDocker主要コマンドまとめも参考にしてください。また、-v オプションと -p オプションの使い方を体系的に学びたい方はポートマッピング(-p)とボリュームマウント(-v)の解説記事もあわせてご覧ください。



コメント