KAKUTA TECH BLOG

Blog Article

Dockerボリュームのマウントについて

はじめに

Docker コンテナで扱うデータをコンテナのライフサイクルから切り離して保存したい場合、ボリュームやバインドマウントを利用します。本記事では、Docker ボリュームとマウントの基本から、バインドマウントとの違い、データを永続化する仕組みまで初心者向けに整理して説明します。

参考リンク

Dockerボリュームとは?

Docker ボリュームは、Docker が作成・管理するデータ保存領域です。コンテナ内に直接データを保存すると、そのデータはコンテナ自身の writable layer に保存されます。そのため、コンテナを削除すると、そのコンテナに保存されていたデータも一緒に失われます。一方、ボリュームをコンテナにマウントして使用すると、データをコンテナのライフサイクルから切り離して保存できます。コンテナを削除した後でもボリューム自体は残るため、新しく作成したコンテナから同じボリュームを利用できます。Docker 公式ドキュメントでも、ボリュームはコンテナによって生成・利用されるデータを永続化するための仕組みとして説明されています。

また、1 つのボリュームを複数のコンテナからマウントすることもできます。そのため、データベースのデータなど、コンテナを削除しても残しておきたいデータを保存する用途に向いています。ただし、ボリュームのデータをホスト側の特定のディレクトリから直接操作したい場合には、ボリュームではなくバインドマウントが適しています。

Dockerボリュームを使うメリット

Docker ボリュームを利用すると、コンテナとデータのライフサイクルを分離できます。例えば、データベースのコンテナを削除して新しいコンテナを作り直しても、同じボリュームを再びマウントすれば、以前のデータを利用できます。また、ボリュームは Docker によって管理されるため、ホスト上の特定のディレクトリ構成に直接依存するバインドマウントとは異なり、データを Docker の管理対象として扱えます。さらに、同じボリュームを複数のコンテナから利用することもできます。

ボリュームの作成

Docker CLI を使ってボリュームを作成できます。

docker volume create my_volume

作成したボリュームは、docker volume ls で一覧を確認できます。

docker volume ls

ボリュームをコンテナにマウントする

作成したボリュームは、コンテナのディレクトリにマウントして利用します。

docker run --mount source=my_volume,target=/data my_image

source が Docker ボリュームの名前、target がコンテナ内のマウント先です。-v または --volume を使って指定することもできます。

docker run -v my_volume:/data my_image

Docker 公式ドキュメントでは、--mount のほうが指定方法が明示的で、利用できるオプションも分かりやすいため、基本的には --mount の使用が推奨されています。

マウントとは

Docker におけるマウントとは、ホスト上のディレクトリや Docker が管理するボリュームなどを、コンテナ内の特定のパスから利用できるようにする仕組みです。コンテナは基本的にホストのファイルシステムから分離されているため、ホスト上にあるファイルやディレクトリをそのままコンテナから利用できるわけではありません。そこで、必要なデータをコンテナ内のパスにマウントします。Docker では、ボリュームマウントやバインドマウントなど、複数の種類のストレージマウントが用意されています。

重要なのは、「ボリューム」と「マウント」は同じものではないという点です。ボリュームは Docker が管理する保存領域であり、マウントは、そのボリュームなどをコンテナ内から利用できる状態にする操作です。例えば my_volume というボリュームを /data にマウントすると、コンテナからは /data を通してボリュームに保存されたデータを読み書きできます。

バインドマウント

バインドマウントは、ホストマシン上の特定のファイルやディレクトリを、コンテナ内のパスに直接マウントする方法です。Docker が管理するボリュームを使うのではなく、ホスト上に存在する場所をそのまま指定します。そのため、ホスト側からファイルを直接確認したり編集したりしたい場合に適しています。特に開発環境では、ホスト側でソースコードを編集すると、その変更をコンテナからすぐに利用できるため、開発中のソースコードをコンテナに共有する用途などで利用されます。

バインドマウントの基本構文

docker run --mount type=bind,source=/host/path,target=/container/path my_image

source がホスト側のファイルやディレクトリ、target がコンテナ側のマウント先です。

-v を使って、次のように指定することもできます。

docker run -v /host/path:/container/path my_image

バインドマウントの特徴

バインドマウントでは、コンテナからファイルを変更すると、その変更がホスト側のファイルにも反映されます。逆に、ホスト側でファイルを変更すると、その変更をコンテナから利用できます。そのため、ソースコードや設定ファイルなど、ホスト側から直接操作したいファイルを扱う場合に便利です。一方で、ホストのファイルシステムへ直接アクセスできるため、コンテナからホスト上のファイルを変更・削除できる点には注意が必要です。必要に応じて読み取り専用の ro や readonly を指定できます。

ボリュームマウント

ボリュームマウントは、Docker が管理するボリュームをコンテナ内のパスにマウントする方法です。バインドマウントとは異なり、ユーザーがホスト上の保存先ディレクトリを直接指定して管理するのではなく、Docker がボリュームの保存場所を管理します。そのため、ホスト側の特定のディレクトリを直接操作する必要がなく、コンテナから生成されるデータを永続的に保存したい場合に適しています。Docker 公式ドキュメントでは、コンテナによって生成・利用されるデータを永続化する場合の推奨手段としてボリュームが説明されています。

ボリュームマウントの基本構文

docker run --mount source=my_volume,target=/data my_image

source にボリューム名を指定し、target にコンテナ内のマウント先を指定します。

-v を使う場合は、次のように記述できます。

docker run -v my_volume:/data my_image

指定したボリュームが存在しない場合、Docker はコンテナの作成時にボリュームを作成できます。

バインドマウントとの違い

バインドマウントとボリュームマウントは、どちらもコンテナの writable layer とは別の場所にデータを保存したり、コンテナと外部のデータを共有したりするために利用できます。ただし、管理方法が異なります。バインドマウントはホスト上の具体的なパスを指定するため、ホストからファイルを直接扱いたい場合に向いています。一方、ボリュームは Docker が保存領域を管理するため、ホスト上の保存場所を意識せずに永続データを扱いたい場合に適しています。

データの永続化

データの永続化とは、コンテナやアプリケーションの停止・再起動・削除などが発生しても、必要なデータを失わずに保持することです。Docker コンテナに直接書き込んだデータは、そのコンテナの writable layer に保存されます。このコンテナを削除すると、その writable layer も削除されるため、そこに保存されていたデータも失われます。そこで、コンテナとは別に管理されるボリュームなどへデータを保存します。そうすることで、コンテナを作り直しても同じボリュームを新しいコンテナにマウントして、以前のデータを引き続き利用できます。

ただし、データを永続化する方法はボリュームだけではありません。ホスト上の特定のファイルやディレクトリを利用したい場合はバインドマウントを使用できます。また、データベースをコンテナの外部で管理する構成であれば、アプリケーションコンテナから外部のデータベースへ接続する方法もあります。重要なのは、コンテナそのものに保存しておきたいデータと、コンテナを削除しても残しておきたいデータを分けて考えることです。

Dockerボリューム

Docker ボリュームは、Docker が管理する保存領域です。コンテナを削除してもボリューム自体は自動的に削除されないため、コンテナとは独立してデータを保持できます。データベースなど、コンテナを作り直しても残しておきたいデータを保存する用途に適しています。

バインドマウント

バインドマウントは、ホスト上のファイルやディレクトリをコンテナから利用する方法です。ホスト側のファイルを直接編集・確認できるため、開発中のソースコードや設定ファイルをコンテナと共有する用途に適しています。

外部データベース

データベースのデータをコンテナ内に保存せず、外部のデータベースサービスや別のデータベースサーバーで管理する方法もあります。この場合、アプリケーションのコンテナが削除されても、データベース側のデータはコンテナのライフサイクルとは独立して保持できます。

まとめ

Docker でデータを扱うときは、コンテナそのものと、コンテナから利用するデータを分けて考えることが重要です。コンテナ内の writable layer に保存したデータはコンテナの削除とともに失われる可能性があるため、長期間保持したいデータにはボリュームなどの外部ストレージを利用します。

ボリュームは Docker が管理する保存領域で、データの永続化に適しています。一方、バインドマウントはホスト上の特定のファイルやディレクトリをコンテナと共有する仕組みで、開発中のソースコードなどを扱う場合に便利です。どちらも「マウント」という仕組みを使ってコンテナ内から利用しますが、誰が保存場所を管理するのかという点に大きな違いがあります。