第07章:DBの永続化(volume)を理解する💾🔒
この章では、**「DBを消さずにコンテナだけ作り直せる」**状態を作ります🎉 やることはシンプルで、Postgresのデータ置き場を 名前付きボリューム(named volume) に逃がすだけです💪
1) まず結論:DBは“コンテナの中”に置いちゃダメ🙅♂️🧨
コンテナは基本「作っては壊す」前提の存在です🧊 なので DBの中身(=大事な状態) をコンテナのファイルシステムに置くと…
docker compose down→ コンテナ消えるdocker compose up→ 新しいコンテナができる- 中身(DB)がまっさらに戻る 😇💥
これを防ぐのが volume(ボリューム) です。
2) volumeのイメージ:コンテナ=使い捨ての家🏠🧹、volume=外付けHDD💾✨
- コンテナ:住む人(プロセス)はここ。引っ越し前提。
- volume:家具や荷物(データ)はここ。引っ越しても持っていく。
Docker公式も、volumeは「Dockerが管理する永続ストレージ」って位置づけです。(Docker Documentation)
3) DBに向いてるのは「名前付きボリューム」💾✅
ざっくり比較するとこう👇
- bind mount(ホストのフォルダ直結):ソースコード共有に強い📁🧑💻
- named volume(Docker管理ストレージ):DBみたいな“状態”に強い💾🛡️
この教材ではDBは named volume推奨でいきます。
4) まずはcompose.yamlに“DB用の金庫”を作る🔐🐘
✅ 最小の完成形(短い書き方)
Postgres公式イメージは、データの置き場が基本 /var/lib/postgresql/data です。(Docker Hub)
ここに named volume をマウントします💾
services:
db:
image: postgres:18
environment:
POSTGRES_PASSWORD: postgres
ports:
- "5432:5432"
volumes:
- pg-data:/var/lib/postgresql/data
volumes:
pg-data:
volumes:(サービス内)…「このサービスはこのvolumeを使うよ」volumes:(トップレベル)…「そのvolumeの名前と存在を宣言するよ」
Docker公式のComposeリファレンスでも、トップレベル volumes で名前付きボリュームを定義して再利用できる、と説明されています。(Docker Documentation)
🔥ポイント
postgres:latestみたいに latest固定は避けて、少なくともpostgres:18みたいに「メジャー固定」がおすすめです。 (再現性が上がって、未来の自分が助かる…!🧠✨) なおPostgreSQL 18は 2025-09-25 にリリースされています。(postgresql.jp)
5) 実験:downしてもデータが残るのを体験しよう🧪✨
5-1) 起動する🚀
docker compose up -d
docker compose ps
5-2) テーブル作って、データ入れる🧱🍣
コンテナ内の psql を叩きます(超ラク)🎮
docker compose exec db psql -U postgres -c "CREATE TABLE IF NOT EXISTS todo(id SERIAL PRIMARY KEY, title TEXT);"
docker compose exec db psql -U postgres -c "INSERT INTO todo(title) VALUES('volumeさいこう');"
docker compose exec db psql -U postgres -c "SELECT * FROM todo;"
ここで volumeさいこう が見えたらOK👀✨
5-3) コンテナを消す(でもvolumeは残す)🧹
docker compose down
5-4) もう一回起動して確認🔁
docker compose up -d
docker compose exec db psql -U postgres -c "SELECT * FROM todo;"
さっきのデータが残ってたら勝ち🏆💾 これが「永続化」!
6) ここ超大事:down と down -v は別物⚠️🧨
-
docker compose down→ コンテナ・ネットワークは消える(でも named volume は消えない) -
docker compose down -v(または--volumes) → Composeファイルで宣言した named volume も消える 😱💥 公式コマンドリファレンスでも-v/--volumesは named volume を削除する、と明記されています。(Docker Documentation)
つまり、こういうこと👇
✅「DB残したい」→ docker compose down
💣「DBも初期化したい」→ docker compose down -v
7) “消していいデータ / 消しちゃダメなデータ”の線引き🧠📏
ここ、設計の最初の山です🏔️✨ 迷ったらこのルールでOK👇
✅ 基本ルール(この教材の運用)
- 消していい:コンテナ、ネットワーク(基本)🧹
- ケースバイケース:イメージ、ビルドキャッシュ(容量次第)📦
- 消しちゃダメ(基本):DBのデータ(named volume)💾🔒
開発で「DBをリセットしたい日」もあります。そのときは “意図して消す” のが設計です👍
8) よくある事故あるある🪤😂(先回りで回避!)
事故①:volumeを付け忘れて、匿名ボリューム地獄👻
Postgres公式イメージは、適切にマウントしないと匿名ボリュームが作られたりして、再作成時に再利用されず「データ消えた?」になりがちです。(Docker Hub) → named volumeを明示が最強💪💾
事故②:マウント先を間違える(超重要)🧨
Postgres公式イメージの注意として、(少なくともPostgreSQL 17まで)
/var/lib/postgresql/data にマウントしろ、/var/lib/postgresql にマウントすると永続化されない場合がある、と書かれています。(Docker Hub)
→ 迷ったら /var/lib/postgresql/data へ✅
事故③:容量が増えて「なんか重い」🐘💦
不要なボリュームが溜まるとディスクを食います🍚
使ってないボリュームの掃除は docker volume prune など。(Docker Documentation)
ただし 本当に不要かは要注意⚠️(消したら戻らない)
9) ちょい設計の話:volume名は衝突しないの?🏷️🤔
普通に書けば、Composeはプロジェクト単位で名前を付けるので、基本はぶつかりにくいです(第4章の“同居”とつながるところ🏙️✨)。
ただし、上級寄りですが…
- あえて共有したい(複数composeから同じDBデータ使う等)なら
name:やexternal:を使うことがあります externalはdownで消されない扱いになります(安全寄り)(Docker ドキュメント)
ここは必要になったタイミングでOK🙆♂️(今は触らなくて大丈夫)
10) AIに頼るなら、こう聞くと強い🤖🧠✨
そのままコピペで使える質問例
- 「Postgresの永続化をnamed volumeでやるcompose.yamlを書いて。マウント先は公式推奨のパスにして」
- 「
downとdown -vの違いを、事故例付きで説明して」 - 「既存のcompose.yamlにDB用volumeを追加して、データが残る検証手順も作って」
AIの答えをレビューする観点👀
volumes:が トップレベルに宣言されてる?- マウント先が
/var/lib/postgresql/dataになってる?(Docker Hub) - “リセット手順”が
down -vになってて、注意書きがある?(Docker Documentation)
11) 理解度チェック(3分)📝⏱️
docker compose downしたのにDBが残るのはなぜ?💾down -vは何を消す?🧨- DBでbind mountよりnamed volumeが向きやすい理由は?🤔
- Postgresのデータディレクトリはどこ?🐘
- “消していい/ダメ”をどう線引きする?📏
まとめ🎉💾
- コンテナは使い捨て、DBは永続化が必要🏠➡️💾
- Postgresは
/var/lib/postgresql/dataに named volume をマウント✅(Docker Hub) downは安全、down -vはDB初期化ボタン💣(Docker Documentation)- これができると「壊して直す」が怖くなくなる😎🔧✨
次の章(第8章)では、環境変数と.envで設定を分離して「直書き地獄」を終わらせます🔑📦✨