Lab 3: ボリュームとデータ永続化

このラボでは、コンテナのデータが消える問題を体験し、ボリュームを使ってデータを永続化する方法を学びます。

1. コンテナのデータは消える問題を体験

コンテナ内に作成したファイルは、コンテナを削除すると消えてしまいます。実際に試してみましょう。

# コンテナを起動してファイルを作成
docker run -it --name test-data ubuntu /bin/bash

# コンテナ内で実行
echo "大切なデータ" > /tmp/important.txt
cat /tmp/important.txt
exit

# コンテナを削除
docker rm test-data

# 新しいコンテナを起動してファイルを確認
docker run -it --name test-data2 ubuntu /bin/bash
cat /tmp/important.txt   # ファイルがない!
exit
docker rm test-data2
⚠️ 重要: コンテナを削除すると、コンテナ内のデータはすべて失われます。データベースのデータやアップロードファイルなど、残したいデータにはボリュームを使う必要があります。

2. Docker ボリュームの管理

# ボリュームを作成
docker volume create my-data

# ボリューム一覧を表示
docker volume ls

# ボリュームの詳細を確認
docker volume inspect my-data
💡 ボリュームとは: Dockerが管理する専用のデータ保存領域です。コンテナを削除してもボリュームは残り、他のコンテナからも利用できます。

3. -v でボリュームマウント

# ボリュームをマウントしてコンテナを起動
docker run -it --name vol-test -v my-data:/app/data ubuntu /bin/bash

# コンテナ内でデータを保存
echo "ボリュームに保存されたデータ" > /app/data/test.txt
exit

# コンテナを削除
docker rm vol-test

# 新しいコンテナで同じボリュームをマウント
docker run -it --name vol-test2 -v my-data:/app/data ubuntu /bin/bash

# データが残っていることを確認!
cat /app/data/test.txt
exit
docker rm vol-test2

4. バインドマウント

ホストマシンのディレクトリを直接コンテナにマウントする方法です。開発時にコードを即座に反映させたい場合に便利です。

# ホストにディレクトリを作成
mkdir -p ~/docker-data
echo "ホストから書いたファイル" > ~/docker-data/hello.txt

# バインドマウントでコンテナを起動
docker run -it --name bind-test -v ~/docker-data:/app/data ubuntu /bin/bash

# コンテナ内からホストのファイルが見える
cat /app/data/hello.txt

# コンテナ内で書き込み → ホストにも反映される
echo "コンテナから書いたファイル" > /app/data/from-container.txt
exit
docker rm bind-test

# ホスト側で確認
cat ~/docker-data/from-container.txt
💡 ボリューム vs バインドマウント:
ボリューム (-v volume-name:/path): Dockerが管理。本番環境向き。
バインドマウント (-v /host/path:/path): ホストのパスを直接指定。開発環境向き。

5. 📝 練習問題: MySQLコンテナでボリューム永続化

課題: MySQLコンテナのデータをボリュームで永続化してみましょう。
  1. ボリューム mysql-data を作成
  2. MySQLコンテナを起動(ボリュームをマウント)
  3. データベースにテーブルを作成してデータを挿入
  4. コンテナを停止・削除
  5. 新しいコンテナを同じボリュームで起動し、データが残っていることを確認

解答例

# 1. ボリューム作成
docker volume create mysql-data

# 2. MySQLコンテナを起動
docker run -d --name my-mysql \
  -e MYSQL_ROOT_PASSWORD=secret \
  -e MYSQL_DATABASE=testdb \
  -v mysql-data:/var/lib/mysql \
  -p 3306:3306 \
  mysql:8.0

# 少し待ってからMySQLに接続(起動に数秒かかります)
sleep 10
docker exec -it my-mysql mysql -uroot -psecret testdb

# MySQL内で実行
CREATE TABLE users (id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(50));
INSERT INTO users (name) VALUES ('太郎'), ('花子');
SELECT * FROM users;
exit

# 3-4. コンテナを停止・削除
docker stop my-mysql
docker rm my-mysql

# 5. 新しいコンテナを同じボリュームで起動
docker run -d --name my-mysql2 \
  -e MYSQL_ROOT_PASSWORD=secret \
  -v mysql-data:/var/lib/mysql \
  -p 3306:3306 \
  mysql:8.0

# データが残っていることを確認
sleep 10
docker exec -it my-mysql2 mysql -uroot -psecret testdb -e "SELECT * FROM users;"

# 後片付け
docker stop my-mysql2
docker rm my-mysql2
docker volume rm mysql-data

← 前のラボ | 次のラボへ → Lab 4: Dockerネットワーク