メインコンテンツまでスキップ

第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) downup しても残るか確認🔁✨

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もファイルも消えます😱
  • 「永続化の実験中は downdown -v を使い分ける」🧠✨

観察コマンド:箱ができたか確認しよう🔎📦

docker volume ls
docker volume inspect <ボリューム名>

「ボリュームはDockerが管理する永続領域で、バックアップ/復元などの管理コマンドがある」っていう公式の立ち位置も押さえておくと強いです💪(Docker Documentation)


AI(Copilot / Codex)での“安全な”使い方🤖🛡️✨

やり方は簡単!でも秘密(パスワード等)は貼らないのが鉄則🔒

例プロンプト(コピペOK)📋

  • 「このcomposeは named volume を正しく定義できてる?間違いがあれば直して🧩」
  • docker compose downdown -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名が思ったのと違う」問題(プロジェクト名プレフィックス等) を、気持ちよく解決していきます😄🔧✨