Skip to content
VDS · Dockerとコンテナ

ボリューム:コンテナデータの実際の保存場所

名前付きボリュームとバインドマウントの違い、ディスク上の物理的な保存場所、コンテナ再作成時にデータベースを失わない方法を解説します。

更新日 2026年8月23日

コンテナは使い捨てです。その中に書き込んだものはすべてコンテナと一緒に消えます。データは外部に置く必要があり、方法はちょうど2つあります。名前付きボリュームと、ホストディレクトリのバインドマウントです。

2つの方法と使い分け

services:
  db:
    image: postgres:17
    volumes:
      - db-data:/var/lib/postgresql/data   # named volume
  app:
    image: nginx:1.27
    volumes:
      - ./site:/usr/share/nginx/html:ro    # directory bind mount
      - ./nginx.conf:/etc/nginx/nginx.conf:ro

volumes:
  db-data:

名前付きボリュームは Docker 自身が作成・保存し、/var/lib/docker/volumes/<name>/_data に置かれます。内部のパーミッションはイメージが自動的に設定します。データベースやサービスの内部状態はこの方法で保持します。

ディレクトリのバインドマウントは、マシンのディスク上の通常のパスです。設定ファイル、Web サイトの静的アセット、証明書を渡すときはこの方法を使います。エディターで編集でき、リポジトリに保存できるので便利です。

:ro フラグを付けるとマウントは読み取り専用になります。コンテナが書き込みアクセスを必要としないすべての場所で使ってください。手軽な保護になります。

実体がどこに保存されるか

docker volume ls
docker volume inspect db-data
docker inspect -f '{{json .Mounts}}' <container> | python3 -m json.tool
sudo du -sh /var/lib/docker/volumes/* | sort -h | tail

最後のコマンドは、ディスク容量が不足したときに最初に実行するものです。詳細はディスク容量をご覧ください。

docker compose down -v と docker volume prune はボリュームを完全に削除します。データベースが入ったボリュームも、コンテナが停止している間は「未使用」に見え、クリーンアップの対象になります。削除の前に一覧を確認してください: docker volume ls -f dangling=true。

コピーと移行

使い捨てコンテナで名前付きボリュームをコピーする:

docker run --rm -v db-data:/from -v $(pwd):/to alpine \
  tar czf /to/db-data.tar.gz -C /from .

復元:

docker volume create db-data
docker run --rm -v db-data:/to -v $(pwd):/from alpine \
  tar xzf /from/db-data.tar.gz -C /to

データベースの場合、この方法はコンテナが停止しているときだけ適しています。稼働中のデータベースをファイルレベルでコピーすると、整合性が崩れる可能性があります。データベース専用のツールである pg_dump、mysqldump でダンプするほうが確実です。何をコピーすべきかもご覧ください。

パーミッション

バインドマウントで最も多いミスは、所有者の不一致です。コンテナ内ではプロセスが独自の UID で動作するため、ホスト側で root が作成したファイルにはアクセスできません。

docker compose exec app id
sudo chown -R 1000:1000 ./data

多くのイメージは PUID/PGID 変数に対応しています。ディレクトリの所有者を変更するより便利です。

よくあるミス

  • コンテナ内にデータを書き込んでいた。 アップデート時にコンテナを再作成したところ、データが消えました。確認方法: docker diff <container> でファイルシステムの変更点を表示できます。そこに大きな書き込みがあれば危険信号です。
  • イメージ内の空でないパスにディレクトリをバインドマウントした。 イメージの内容が隠れてしまい、サービスが自分のファイルを見つけられません。
  • バインドマウントに相対パスを使った。 相対パスは現在のディレクトリではなく、compose.yaml があるディレクトリを基準に解決されます。別の場所から実行すると、新しい空のディレクトリが作成されます。
  • OS の再インストール時にボリュームのことを忘れていた。 再インストールはディスクを完全に消去します。コピーはこのマシン以外に保存する必要があります。