第04章:Composeで“データ箱”を定義する(named volume入門)📦
この章は一言でいうと 「コンテナを作り直してもデータが残る“箱”を、Composeで宣言できるようになる」 です😆👍
Composeの volumes: は、永続データを安全に扱うための基本中の基本なので、ここでしっかり“手で覚える”のが最短ルートです🏃♂️💨
この章でできるようになること🎯
- ✅ Composeで named volume(名前付きボリューム) を定義できる
- ✅ サービス(コンテナ)からそのボリュームをマウントできる
- ✅
downしてもデータが残る /down -vで消える、を体で理解できる💪 - ✅ 「あ、これ bind mount じゃなくて volume だ!」って見分けがつく👀✨
まず超重要:Composeには volumes: が2か所ある😵💫➡️😄
① サービスの中の volumes:(= “このコンテナに何をマウントする?”)🧲
- コンテナ側の
/dataとかに「何をくっつけるか」を書くところ📝
② トップレベルの volumes:(= “named volume を宣言する”)📦
- “箱(ボリューム)そのもの”を定義するところ📦
- 複数サービスで使い回せるのが強い💪✨
- Docker公式も「トップレベルの
volumesは、複数サービスで再利用できる named volume を設定するため」と説明してます。(Docker Documentation)
そしてそもそもボリュームは コンテナエンジンが提供する永続ストレージで、コンテナ停止後もデータが残るのが特徴です。(Docker Documentation) (Composeはそれを“宣言的に”扱えるようにしてくれる感じです🧠✨)(Docker Documentation)
実習A:最小構成で「箱📦」を作って、残るのを確認しよう🧪✨
「DBいきなりはちょい重い…😇」ってなるので、まずは ファイル1本で永続化を体験します👍
1) docker-compose.yml を作る📝
services:
box:
image: alpine:3.20
command: sh -c "date >> /data/hello.txt && echo 'wrote!' && tail -f /dev/null"
volumes:
- mydata:/data
volumes:
mydata:
ポイント💡
mydata:/dataって書いてるので、/data は named volume(箱)につながる🔌- トップレベルの
volumes:にmydata:を宣言してるので、これが“箱の定義”📦
2) 起動する🚀
docker compose up -d
docker compose はDocker CLIに統合されたComposeコマンドとして公式リファレンスがあります。(Docker Documentation)
3) ちゃんと書けてるか見る👀
docker compose exec box sh -c "ls -l /data && echo '---' && cat /data/hello.txt"
4) コンテナを消す(でも箱は残す)🧹➡️📦
docker compose down
5) もう一回起動して確認🔁
docker compose up -d
docker compose exec box sh -c "cat /data/hello.txt"
👉 行が増えてたら成功🎉 「コンテナは作り直してるのに、データは残ってる」= 箱(volume)が本体って感覚が掴めます😄✨
6) 最後に“箱ごと”片付ける🗑️📦(注意⚠️)
docker compose down -v
-vを付けると ボリュームも消えるので、戻せません😱- 「消したくないデータがある時は絶対に
-v付けない」これ鉄則です🧯
実習B:実務っぽく「DBの箱📦」をComposeで定義する🐘✨
ここからは「DBコンテナのデータをvolumeに入れる」王道パターンです👑 (DBの“正確な保存パス”は第7章でガッツリやるので、ここは “箱につなぐ”が主役です😉)
1) Postgresのイメージタグは“安定系”を選ぼう🧷
Docker HubのPostgres公式イメージは、17-bookworm みたいに Debianスイート名付きタグがあります。(Docker Hub)
そしてDocker公式イメージ側の議論として、スイート名なしタグ(例: postgres:17)はOS世代が動く可能性があるので避けたい、という注意も出ています。(GitHub)
なのでこの教材では postgres:17-bookworm みたいな形で進めます👍
2) docker-compose.yml(DB + named volume)📝
services:
db:
image: postgres:17-bookworm
environment:
POSTGRES_PASSWORD: postgres
POSTGRES_USER: postgres
POSTGRES_DB: appdb
ports:
- "5432:5432"
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:
ここでやってることは超シンプル👇
pgdataという 箱📦(named volume) を作る- DBのデータ領域に 箱を接続する
(Composeのトップレベル
volumesはこの“箱宣言”のためにあります)(Docker Documentation)
3) 起動🚀
docker compose up -d
4) DBに入ってテーブル作る🏗️
docker compose exec -it db psql -U postgres -d appdb
psqlの中で👇
create table notes(id serial primary key, body text);
insert into notes(body) values ('hello volume!');
select * from notes;
quit で出ます。
5) down → up しても残るか確認🔁✨
docker compose down
docker compose up -d
docker compose exec -it db psql -U postgres -d appdb -c "select * from notes;"
👉 データが出たら成功🎉 「DBコンテナは消えても、箱(pgdata)が残る」 を体感できました😄📦🐘
ここで詰まりがちポイント集🪤(先回りで回避😎)
❌ 1) トップレベルの volumes: を書き忘れる
- サービス側で
mydata:/dataって書いたのに、箱の宣言がないやつ😇 - Composeの思想的には「箱を宣言して使う」なので、基本セットで覚えよう📦✨(Docker Documentation)
❌ 2) ./data:/data って書いて「あれ?これnamed volume?」になる
- それは bind mount(ホストフォルダ直結)です👀
- named volume は 左側が“名前” になってるやつ(例
mydata:/data)📦
❌ 3) docker compose down -v しちゃった
- 箱ごと削除なので、DBもファイルも消えます😱
- 「永続化の実験中は
downとdown -vを使い分ける」🧠✨
観察コマンド:箱ができたか確認しよう🔎📦
docker volume ls
docker volume inspect <ボリューム名>
「ボリュームはDockerが管理する永続領域で、バックアップ/復元などの管理コマンドがある」っていう公式の立ち位置も押さえておくと強いです💪(Docker Documentation)
AI(Copilot / Codex)での“安全な”使い方🤖🛡️✨
やり方は簡単!でも秘密(パスワード等)は貼らないのが鉄則🔒
例プロンプト(コピペOK)📋
- 「このcomposeは named volume を正しく定義できてる?間違いがあれば直して🧩」
- 「
docker compose downとdown -vの違いを、初心者向けに例え話で説明して📦」 - 「この
volumes:は bind mount? named volume?理由も添えて👀」
小テスト(3分)✍️✨
Q1. docker compose down で named volume は消える?
Q2. mydata:/data の左側 mydata は何?
Q3. down -v を使うと何が起きる?
解答✅
- A1. 基本消えない(コンテナやネットワークは消えるけど箱は残る)📦
- A2. named volume の名前(箱の名前)📦
- A3. 箱(volume)も削除され、永続データも消える😱🗑️
次の第5章では、この章でちょい匂わせた 「volume名が思ったのと違う」問題(プロジェクト名プレフィックス等) を、気持ちよく解決していきます😄🔧✨