Dockerのデータ永続化
Dockerを利用する際、データ永続化は非常に重要な概念です。
デフォルトでは、Dockerコンテナ内のデータはコンテナが削除されると失われます。
これを防ぐために、データ永続化の仕組みを理解し適切に設定する必要があります。
本記事では、Dockerでのデータ永続化について詳しく解説します。
1. データ永続化の重要性
Dockerコンテナは一時的な環境で動作することを前提としています。
そのため、コンテナが停止、再起動、または削除されると、内部に保存されたデータは消えてしまいます。
例えば、データベースコンテナを運用している場合、データが失われると業務に重大な影響を与える可能性があります。
データ永続化を設定することで、以下のメリットがあります。
- コンテナの削除や再作成後もデータが保持される。
- ホストマシンとデータを共有できる。
- バックアップやリストアが容易になる。
2. データ永続化の方法
Dockerでデータ永続化を実現する方法には主に以下の3つがあります。
ボリューム (Volumes)
ボリュームは、Dockerが提供するデータ永続化のための最適な方法です。
Dockerの管理下にあり、以下の特徴があります。
- コンテナ間でデータを共有可能。
- ホストマシンのファイルシステムとは独立して管理される。
- Dockerのバックアップや移行ツールと統合しやすい。
ボリュームを使用するには、以下のように設定します。
# ボリュームの作成
$ docker volume create my_volume
# コンテナにマウント
$ docker run -d --name my_container -v my_volume:/data my_image
ボリュームのYAMLファイルの例
以下は、ボリュームを使用したdocker-compose.ymlの例です。
version: '3.8'
services:
app:
image: my_image
volumes:
- my_volume:/data
volumes:
my_volume:
ボリュームの構成イメージ
+-------------------+ +-------------------+
| Host System | | Docker Volume |
| | | |
| | <----> | /var/lib/docker/volumes/my_volume/_data |
+-------------------+ +-------------------+
|
v
+----------------+
| Docker Container|
| /data |
+----------------+
docker volume create コマンドを使用しない場合
docker volume createコマンドを明示的に実行しない場合でも、Dockerは必要に応じてボリュームを自動的に作成します。
- 自動作成の仕組み:
- ボリューム名を指定せずに
-v /container/pathの形式を使用すると、Dockerは匿名ボリューム(ランダムな名前のボリューム)を作成してマウントします。 - ボリューム名を指定して
-v my_volume:/container/pathとした場合、そのボリュームが存在しなければDockerが自動的に作成します。
- ボリューム名を指定せずに
- 注意点:
- 匿名ボリュームは名前がランダムで管理が難しくなるため、運用環境では推奨されません。
- 名前付きボリュームを使用することで、管理や再利用が容易になります。
# 匿名ボリュームが自動作成される例
$ docker run -d --name my_container -v /data my_image
# 名前付きボリュームが自動作成される例
$ docker run -d --name my_container -v my_volume:/data my_image
バインドマウント (Bind Mounts)
バインドマウントでは、ホストマシン上の特定のディレクトリをコンテナにマウントします。
この方法は柔軟性が高く、以下の特徴があります。
- ホストマシンのディレクトリやファイルに直接アクセス可能。
- 開発環境でコードやデータを共有するのに便利。
バインドマウントを使用するには、以下のように設定します。
# バインドマウントを指定
$ docker run -d --name my_container -v /host/path:/container/path my_image
# --mountオプションを使用したバインドマウント
$ docker run -d --name my_container --mount type=bind,source=/host/path,target=/container/path my_image
バインドマウントのYAMLファイルの例
以下は、バインドマウントを使用したdocker-compose.ymlの例です。
version: '3.8'
services:
app:
image: my_image
volumes:
- /host/path:/container/path
バインドマウントのイメージ
+-------------------+
| Host System |
| |
| /host/path |
+-------------------+
|
v
+-------------------+
| Docker Container |
| /container/path |
+-------------------+
tmpfs マウント
tmpfsマウントは、コンテナ内の一時的なデータ保存に使用されます。
データはコンテナのメモリに保存されるため、コンテナが停止すると消去されます。
この方法は、高速な読み書きが必要な場合や、データを永続化する必要がない場合に適しています。
tmpfsマウントを使用するには、以下のように設定します。
# tmpfs マウントの例
$ docker run -d --name my_container --tmpfs /container/tmp my_image
# --mountオプションを使用したtmpfsマウント
$ docker run -d --name my_container --mount type=tmpfs,target=/container/tmp,tmpfs-size=64m my_image
tmpfsマウントのYAMLファイルの例
以下は、tmpfsマウントを使用したdocker-compose.ymlの例です。
version: '3.8'
services:
app:
image: my_image
deploy:
resources:
reservations:
memory: 64m
tmpfs:
- /container/tmp
tmpfsマウントのイメージ
+-------------------+
| Docker Container |
| |
| /container/tmp |
| (Stored in Memory)|
+-------------------+
–mountオプションについて
Dockerでは、--mountオプションを使用してマウントを定義できます。このオプションは-v(--volume)よりも詳細で柔軟な設定が可能です。
--mountオプションの構文
--mount type=<type>,source=<source>,target=<target>[,additional options]
主なパラメータ
type: マウントの種類を指定します。volume: Dockerが管理するボリュームを使用。bind: ホストマシン上のディレクトリを使用。tmpfs: メモリ上に一時的なファイルシステムを作成。
source: マウント元を指定します。type=volumeの場合、ボリューム名を指定。type=bindの場合、ホストのディレクトリやファイルのパスを指定。type=tmpfsの場合、このパラメータは不要。
target: コンテナ内でのマウント先を指定します。- 追加オプション(任意):
readonly: マウントを読み取り専用にする。tmpfs-size:type=tmpfsの場合に使用するメモリサイズを指定。nocopy: ボリュームの初期データコピーを防ぐ(type=volumeの場合)。
使用例
ボリュームを使用した例
docker run -d --name my_container --mount type=volume,source=my_volume,target=/data my_image
バインドマウントの例
docker run -d --name my_container --mount type=bind,source=/host/path,target=/container/path my_image
tmpfsマウントの例
docker run -d --name my_container --mount type=tmpfs,target=/container/tmp,tmpfs-size=64m my_image
-vオプションとの比較
| 特徴 | -v(--volume) | --mount |
|---|---|---|
| 可読性 | やや低い | 高い |
| 設定項目の詳細度 | シンプルな設定向き | 複雑な設定も可能 |
| サポートするマウントの種類 | ボリューム、バインド | ボリューム、バインド、tmpfs |
| 追加オプション | 限定的 | より多様なオプションに対応 |
--mountオプションは、複雑な設定が必要な場合や可読性を高めたい場合に適しています。
一方、簡単な設定には-vオプションを使用することも依然として有効です。
データの同期
データの同期は、ホストマシンとコンテナ間でデータが一貫していることを保証する重要な要素です。以下にボリューム、バインドマウント、およびtmpfsでの同期について説明します。
3.1 ボリュームを使用した場合
- 同期の仕組み:
ボリュームはDockerが管理するため、ホストマシンとの明示的な同期は発生しませんが、ボリューム内のデータはコンテナ間で自動的に共有されます。 - 注意点:
ボリュームに保存されたデータは、DockerのAPIを介してアクセスするのが推奨されます。直接ホストファイルシステムで操作する場合、データ不整合が発生する可能性があります。
3.2 バインドマウントを使用した場合
- 同期の仕組み:
バインドマウントでは、ホストマシン上のディレクトリやファイルがそのままコンテナにマウントされます。
変更はリアルタイムで反映されます。 - 注意点:
- 一部のファイルシステム(特にWindows)では、ホストとコンテナ間でのファイル変更の検知に遅延が発生する場合があります。
- ファイルの権限や所有者の違いによるアクセス制限に注意が必要です。
3.3 tmpfs マウントを使用した場合
- 同期の仕組み:
データはコンテナ内のメモリに保存され、ホストマシンとは同期されません。 - 注意点:
- 一時的なデータに限られるため、コンテナ外での共有や永続化には利用できません。
ボリューム、バインドマウント、tmpfs マウントの比較
| 特徴 | ボリューム | バインドマウント | tmpfs マウント |
| 管理 | Dockerが管理 | ホストマシンの管理 | メモリ上で管理 |
| 使用用途 | 運用環境、データベースなど | 開発環境、ホストとのデータ共有 | 一時的な高速データ保存 |
| パフォーマンス | 最適化されている | 若干のオーバーヘッドがある | 非常に高速 |
| セキュリティ | より安全 | ホストへの直接アクセスが可能 | メモリのみでより安全 |
| データ同期 | Docker管理の範囲内で同期 | ホストとのリアルタイム同期 | 同期なし(メモリ内のみ) |
まとめ
Dockerでのデータ永続化は、運用環境での安定性やデータ保護に直結する重要な要素です。
ボリューム、バインドマウント、tmpfsマウントの違いを理解し、適切な方法を選択することで、効率的かつ安全なシステム運用が可能になります。
データの損失を防ぎ、運用効率を高めるために、ぜひ今回紹介した方法を活用してください。

