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

第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) ここ超大事:downdown -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: を使うことがあります
  • externaldown で消されない扱いになります(安全寄り)(Docker ドキュメント)

ここは必要になったタイミングでOK🙆‍♂️(今は触らなくて大丈夫)


10) AIに頼るなら、こう聞くと強い🤖🧠✨

そのままコピペで使える質問例

  • 「Postgresの永続化をnamed volumeでやるcompose.yamlを書いて。マウント先は公式推奨のパスにして」
  • downdown -v の違いを、事故例付きで説明して」
  • 「既存のcompose.yamlにDB用volumeを追加して、データが残る検証手順も作って」

AIの答えをレビューする観点👀

  • volumes:トップレベルに宣言されてる?
  • マウント先が /var/lib/postgresql/data になってる?(Docker Hub)
  • “リセット手順”が down -v になってて、注意書きがある?(Docker Documentation)

11) 理解度チェック(3分)📝⏱️

  1. docker compose down したのにDBが残るのはなぜ?💾
  2. down -v は何を消す?🧨
  3. DBでbind mountよりnamed volumeが向きやすい理由は?🤔
  4. Postgresのデータディレクトリはどこ?🐘
  5. “消していい/ダメ”をどう線引きする?📏

まとめ🎉💾

  • コンテナは使い捨て、DBは永続化が必要🏠➡️💾
  • Postgresは /var/lib/postgresql/datanamed volume をマウント✅(Docker Hub)
  • down は安全、down -v はDB初期化ボタン💣(Docker Documentation)
  • これができると「壊して直す」が怖くなくなる😎🔧✨

次の章(第8章)では、環境変数と.envで設定を分離して「直書き地獄」を終わらせます🔑📦✨