このラボでは、コンテナのデータが消える問題を体験し、ボリュームを使ってデータを永続化する方法を学びます。
コンテナ内に作成したファイルは、コンテナを削除すると消えてしまいます。実際に試してみましょう。
# コンテナを起動してファイルを作成
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
# ボリュームを作成
docker volume create my-data
# ボリューム一覧を表示
docker volume ls
# ボリュームの詳細を確認
docker volume inspect my-data
# ボリュームをマウントしてコンテナを起動
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
ホストマシンのディレクトリを直接コンテナにマウントする方法です。開発時にコードを即座に反映させたい場合に便利です。
# ホストにディレクトリを作成
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
# 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