Docker Volumeの使い方でデータを永続化する方法をやさしく解説

DevOps

はじめに

Dockerを使ってサービス開発や学習を始めると「コンテナを消したらデータが消えてしまうのでは?」という不安を持つ人もいるでしょう。 確かにコンテナは一時的に動く仕組みなので、そのままではコンテナ停止のたびにデータが消えてしまう場合があります。 そこで登場するのが Docker Volume (ボリューム) です。

ボリュームを使うと、Dockerコンテナを停止・削除してもデータを保持できます。 いわゆるデータの永続化が可能になり、データベースなど保存領域を必要とするアプリケーションをコンテナ上で扱いやすくなります。 ただ、初心者にとっては「どんな種類があるの?」「どこにファイルが保存されるの?」など、分からないことが多いかもしれません。

このページでは、プログラミング未経験やこれからDockerを学ぼうと思う人でも分かるように、Docker Volumeの仕組みと具体的な使い方を丁寧に解説します。 実際の開発現場ではどのようなシーンで使うのか、どのように設定するのかもあわせて解説するので、ぜひ参考にしてください。

この記事を読むとわかること

  • Docker Volumeの基本的な考え方と種類
  • Volumeを利用したコンテナのデータ永続化の方法
  • 開発シーンでのVolume使用例
  • Bind Mountとの違いと使い分け
  • Docker Composeを使ったVolume管理のイメージ

Docker Volumeとは何か?

Docker Volumeは、コンテナ外部にデータを保存するための仕組みです。 コンテナは仮想環境の一種で、基本的にはコンテナ内部がいわば「一時ファイル置き場」です。 そのため、コンテナを破棄すると中にあったデータは一緒に消えてしまう可能性があります。

ここでVolumeを設定すると、コンテナが利用するファイルシステムの一部をホストマシンにある専用領域と紐づけることができます。 コンテナ側から見ると、まるで通常のディレクトリのように見えますが、実体はホスト上に残るため、コンテナを消してもデータが失われません。 たとえば、MySQLなどのデータベースをDockerで動かす場合、Volumeを使うことでコンテナ再起動後もデータを保持できます。

また、同じボリュームを複数のコンテナで共有することも可能です。 これによって、アプリケーションコンテナからログを集約したり、Webサーバーとアプリケーションサーバーの間でファイルをやり取りしたりするような場面でも役立ちます。 単純な学習用のプロジェクトから、本格的なサービスまで幅広く使用される基本機能だと考えてください。

Docker Volumeのメリットと役割

データの永続化

Volumeの最大の役割は データの永続化 にあります。 コンテナ自身が消えてもVolume上のデータはホスト側に保持されるため、再度コンテナを起動して同じVolumeをマウントすれば、前回の作業内容を引き継げます。

コンテナ間のデータ共有

Volumeを共有することで、複数のコンテナ間で同じファイルやデータをやり取りできます。 たとえば、あるコンテナで生成したレポートファイルを別のコンテナで読み込むという使い方も可能です。

セキュリティと分離

ボリュームを使うことで、ホスト側ファイルシステムの特定領域だけをコンテナに開放します。 これにより、ホスト全体へのアクセスを制限しながら、データのやり取りを安全に行うことができます。

Docker Volumeの種類

Dockerでは主に以下の種類のVolumeが使われます。 それぞれの特徴を理解すると、開発や運用での使い勝手が大きく変わります。

Named Volume(名前付きボリューム)

Dockerが管理する領域にボリュームを作成し、それに名前をつけて使用します。 ホスト側のディレクトリパスを明示的に指定しない代わりに、Docker内部でどのパスに保存されるかを自動で管理してくれます。 複数のコンテナから同じ名前のボリュームを参照すれば、同一データを共有できます。

Bind Mount(バインドマウント)

ホスト側の特定フォルダをコンテナ内部にマウントする方法です。 例えばホストの ~/myapp/data ディレクトリをコンテナの /app/data と紐づける、などが可能です。 ホストで開発しているファイルを直接コンテナに渡せるため、開発中は便利です。 一方、ホスト側のファイルパスを間違って指定すると、思わぬファイルが上書きされるリスクもあるため注意が必要です。

Volumeを利用する典型的なシーン

シーン1: ローカル開発環境でのデータベース

MySQLやPostgreSQLをDockerコンテナで動かす場合、Volumeを設定しておかないと、コンテナを再起動した際にテーブルやレコードが消えてしまいます。 Volumeを使えば、何度再起動してもデータを保持できます。 これは学習用の環境構築でも基本的によく使われる設定です。

シーン2: ログファイルの収集

アプリケーションコンテナ内で生成したログを、ホスト上のVolumeに保存することで保管し続けられます。 コンテナを入れ替えたり、スケールアウトのために新しいコンテナを起動したりしても、ログの蓄積が途切れにくくなります。

シーン3: バックアップやマイグレーション

Volumeで保存しているデータをホスト側でバックアップできるようにしておけば、システム移行や障害対応が簡単になります。 また、Volumeを丸ごと別の環境に移動させることで、同じデータを持つサービスを別環境で再現できる場合もあります。

代表的なDocker Volumeの使い方

シンプルなNamed Volume

Named Volumeを利用する場合、まずVolumeを作成してからコンテナを起動する方法があります。 docker volume create mydata のように名前を付けて作成し、コンテナ起動時に -v mydata:/app/data と指定します。 ここでは /app/data がコンテナ内でデータを保存するパスです。 例えば以下のようにMySQLを起動するときに使うことが多いです。

docker volume create mydata

docker run -d \
  --name mymysql \
  -e MYSQL_ROOT_PASSWORD=rootpass \
  -v mydata:/var/lib/mysql \
  mysql

この例では、 mydata というVolumeがコンテナの /var/lib/mysql にマウントされています。 コンテナを停止・削除しても mydata はホストに残っているため、再度コンテナを作り直しても同じデータにアクセスできます。

Bind Mount

Bind Mountを使うには -v ホストディレクトリ:コンテナディレクトリ という形式で指定します。 例えば、ホストの ~/myproject/logs をコンテナの /var/log/app にマウントする場合は次のようになります。

docker run -d \
  --name myapp \
  -v ~/myproject/logs:/var/log/app \
  myapp-image

こうしておけば、ホスト側の ~/myproject/logs ディレクトリとコンテナ側のログディレクトリが同期されます。 ローカルでログを確認したいときや、任意のファイルをコンテナ外から編集したいときによく用いられる方法です。

複数のVolumeを使い分ける

Docker Runのオプションで複数の -v を指定すれば、複数のディレクトリをマウント可能です。 データベース用、ログ用、アプリの設定ファイル用など、用途ごとにVolumeを分けることで管理が楽になります。

Docker ComposeでのVolume管理

Docker Composeを使うと、 docker-compose.yml ファイル内でVolumeを一括管理できます。 たとえば以下のような構成が考えられます。

version: "3"
services:
  app:
    image: myapp-image
    volumes:
      - myapp-logs:/var/log/app
    depends_on:
      - db

  db:
    image: mysql
    environment:
      - MYSQL_ROOT_PASSWORD=rootpass
    volumes:
      - mydb-data:/var/lib/mysql

volumes:
  myapp-logs:
  mydb-data:

Composeファイルで volumes: を定義し、そこに名前を付けておきます。 上記の例では、 myapp-logsmydb-data という2つのNamed Volumeを作成し、それぞれのコンテナに割り当てています。 これにより、Composeコマンドで一括起動すると自動的にVolumeが作られ、コンテナのデータ永続化が実現できます。

Volume運用時の注意点

Volumeの寿命管理

Volumeを作ったはいいものの、不要になっても自動では削除されません。 不要なVolumeを放置すると、ホストディスクの容量を消費し続けることになります。 必要に応じて手動で docker volume rm <volume名> を実行してクリーンアップしましょう。

権限や所有者の設定

コンテナ内のユーザー権限と、ホスト側のディレクトリ権限が一致しない場合、書き込みや読み取りが失敗することがあります。 特にBind Mountを使うときには、ホスト側ディレクトリの権限をしっかり設定しておく必要があります。

データ破損リスク

通常の使用では問題ありませんが、ホスト側がクラッシュしたり、ストレージが突然読み書き不能になったりすると、Volumeにも影響が及ぶ可能性があります。 大切なデータは、別途バックアップを取得するなど多重の対策をしておくと安心です。

ボリュームのデータ自体はホストの特定の場所に保管されますが、そのパスはシステム環境により異なります。 Dockerが管理するNamed Volumeの場合は、ホストの/var/lib/docker/volumes配下にデータが格納されることが多いです。

実務でよく使われるテクニック

データベース+アプリケーションのコンテナ間連携

実務では、MySQLやPostgreSQLなどのデータベースコンテナとアプリケーションコンテナを同時に起動する場面がよくあります。 ここでデータベース用Volumeを使わずに何度もコンテナを再作成すると、データが消えてしまい開発効率が下がります。 そのため、本番環境でも開発環境でもVolumeをセットアップしておき、安心して再起動できる環境を整えるのが定番です。

複数環境でのデータ引き継ぎ

ステージング環境から本番環境へデータを移行する際に、Named Volumeのディレクトリごとアーカイブし、別のホスト環境へ持っていくことがあります。 アプリケーションのイメージや設定はDockerfileやComposeで再現できても、データだけは個別に扱う必要があるため、Volumeのバックアップが大事です。

CI/CDパイプラインでのキャッシュ利用

CI/CD(継続的インテグレーション/継続的デリバリー)環境では、ビルド結果をVolumeにキャッシュしてビルド時間を短縮するテクニックが使われることがあります。 テストやビルドに必要なライブラリをVolumeに置いておき、同じコンテナ上で何度もビルドを繰り返すケースです。 これによって、余計なダウンロードやインストールを繰り返す手間が減ります。

Bind MountとNamed Volumeの使い分け

Bind Mountのメリット

  • ホスト上のファイルを直接編集・確認できるので、開発効率が高い
  • ディレクトリ構造を細かく指定しやすい

Bind Mountのデメリット

  • ホスト側のファイルを誤って消去・変更するリスクがある
  • ホスト環境によってディレクトリのパスが異なると設定を引き継ぎにくい

Named Volumeのメリット

  • Dockerが自動でディレクトリを管理するため、開発者が場所を意識しなくていい
  • マルチホストや複数のコンテナ間で同じ設定を適用しやすい

Named Volumeのデメリット

  • ホスト上のファイルを直接確認するには少し手間がかかる
  • Volumeが増えすぎると、どれが何のために作られたか把握しにくくなる

本番運用でもBind Mountを使う場面はありますが、設定ミスに注意が必要です。 また、複数人が開発や運用を行うチーム環境では、Named Volumeを使うほうがトラブルを避けやすい場合もあります。

Docker Volumeの削除と管理

不要なVolumeの削除

先述のように、Volumeはコンテナと独立したリソースなので、コンテナを消してもVolumeは残ります。 長期運用の中で不要になったVolumeが増えるとディスクを圧迫するため、適宜クリーンアップを行うことが望ましいです。

不要なVolumeをリストアップするには docker volume ls コマンドを使います。 そこで名前を確認して、 docker volume rm volume名 で削除できます。 Dockerが作成した匿名ボリュームなど、一括で削除したい場合は docker volume prune を使うと便利です。

運用管理のポイント

命名規則を決める

例: プロジェクト名と用途をVolume名に含めることで、何のデータが格納されているか分かりやすくなります。

バックアップ方針を立てる

Volumeに重要なデータを保存するなら、バックアップの取り方と頻度を明確にしておきましょう。

チーム内での共有

チームでの開発時には、Volumeの使い分けやBind Mountのパスをドキュメント化しておくことが大事です。

コンテナのデータ消失を防ぐ考え方

コンテナはあくまで一時実行環境

コンテナ内部のファイルシステムは、再起動やコンテナ破棄時にクリアされるのが基本です。 そのため、保存が必要なデータは常にVolume(Named VolumeまたはBind Mount)を通してホストや外部ストレージに置くべきだと考えておくと安心です。

バックアップとテストの両輪

本番稼働中のコンテナが予期せず落ちたとき、Volumeにデータがあるから大丈夫……というケースは多いものの、万が一ホストが破損したら、そのVolume自体が読み取れなくなる可能性も考えられます。 バックアップと復元の手順をテストしておくことで、本当に安全な運用が実現できます。

まとめ

Docker Volumeは、コンテナを効率的に活用するうえで欠かせない機能です。 コンテナの軽量さや再現性を活かしつつ、必要なデータを永続化することで安定した開発・運用環境を手にできます。

Volumeには大きく分けてNamed VolumeとBind Mountがあり、それぞれに特徴があります。 ローカル環境でファイルを同期しながら開発するならBind Mountを活用したり、チーム開発で本番環境を作るならNamed Volumeを使ったりと、シーンに合わせて適切に選択することが大切です。

不要なVolumeを定期的に掃除する、バックアップを取るなど運用面の知識も併せて身につけておくと良いでしょう。 これらのポイントを押さえれば、Dockerを使ったプロジェクトでも安心してデータを扱えるようになります。

以上で、Docker Volumeの基本とデータ永続化についての説明は終わりです。 これから実際にコンテナを立ち上げ、Volumeを指定して使ってみると、学習や開発がよりスムーズに進むのではないでしょうか。

Dockerをマスターしよう

この記事で学んだDockerの知識をさらに伸ばしませんか?
Udemyには、現場ですぐ使えるスキルを身につけられる実践的な講座が揃っています。