Skip to main content

第17章:DBデータはどう守る?(永続化の考え方)🛡️

この章はひと言でいうと—— **「コンテナは消してOK。でもDBは消えたら泣く😭」**を卒業する回です🎓✨


この章でできるようになること✅😊

  • **“消えて困るデータ”“消えても困らないデータ”**を仕分けできる📦🧠
  • DBを Volume(ボリューム)で永続化して、コンテナを消してもデータを残せる🧱🗃️
  • 「データ消えた😱」の**ありがち罠(匿名ボリューム / マウント先ミス)**を回避できる🪤💥

1) まず結論:DBは「コンテナの中」に置かない🙅‍♂️🗑️

コンテナは基本「使い捨ての箱」📦 箱の中(コンテナの書き込み領域)にDBを置くと、箱を捨てた瞬間に一緒に消えます😇

そこで登場するのが VolumeVolumeは“コンテナの寿命とは別”にデータを保持できる仕組みです🧱✨(コンテナを消しても残る!)(Docker Documentation)


2) “永続化”の選択肢:Volume と Bind mount の違いざっくり⚖️

✅ DBには基本「Volume」推し🧱🗃️

  • Dockerが管理する保管場所にデータを置く
  • コンテナを作り直してもデータが残る
  • --mount が推奨(明示的で事故りにくい)(Docker Documentation)

✅ ソースコード共有には「Bind mount」便利📁⚡

  • ホスト側のフォルダをそのままコンテナに見せる
  • ただし ホストのファイルをコンテナが直接書き換え可能になりやすく、ホスト依存も強い(安全面・移植性の注意)(Docker Documentation)
  • Docker DesktopはLinux VM上で動くので、ファイル共有の仕組みが絡みます(Docker Documentation)

3) 仕分けワーク:「消えて困る?困らない?」📋🧠✨

まずはこれだけ覚えると強いです💪😄

データ消えたら?置き場所おすすめ
永続データ(絶対守る)DB本体、ユーザー投稿、アップロード画像😱致命傷Volume(基本)🧱
再生成できるデータキャッシュ、ビルド成果物😌再作成OKコンテナ内 / tmp / 必要ならVolume
開発だけの一時データローカル検証用の雑データ😅まあOKコンテナ内(捨てやすく)

4) ハンズオン:PostgreSQLで「消しても残るDB」を体験しよう🐘🧪🎮

ここでは PostgreSQL の公式Dockerイメージを使って、永続化の“手触り”を掴みます✋✨ ポイント:**PostgreSQL 18+ で“マウント先が変わった”**ので、そこも最新仕様でやります(ここ大事!)(hub.docker.com)


Step 0:お片付け(前回のが残ってたら)🧹

docker rm -f pg-bad pg-good 2>/dev/null || true
docker volume rm todo_pgdata 2>/dev/null || true

Step 1:わざと失敗(永続化しないで作る)😈🪤

まずは「箱の中にDBを置くとどうなるか」を体験します。

docker run -d --name pg-bad \
-e POSTGRES_PASSWORD=pass1234 \
postgres:18

DBにテーブル作って、1件入れます✍️

docker exec -it pg-bad psql -U postgres -c \
"CREATE TABLE IF NOT EXISTS todos(id serial PRIMARY KEY, title text);
INSERT INTO todos(title) VALUES ('first todo');
SELECT * FROM todos;"

👉 ちゃんと入ってますね😊✅

次にコンテナを消します(箱を捨てる🗑️)

docker rm -f pg-bad

そして “新しく” 作り直す:

docker run -d --name pg-bad \
-e POSTGRES_PASSWORD=pass1234 \
postgres:18

確認:

docker exec -it pg-bad psql -U postgres -c "SELECT * FROM todos;"

たぶん **「テーブル無いよ!」**って言われます😇💥 → これが「コンテナ内にデータを置いた」時の感覚です。

さらに罠:PostgreSQLイメージは内部で 匿名ボリュームが絡むことがあり、 「残ってるのに“次のコンテナ”が使ってない」状態が起きます🪤 公式も“マウント先を間違えると永続化されない”と強く注意しています(hub.docker.com)


Step 2:正解(Named VolumeでDBを守る)🧱🛡️

今度は Named Volume を作って、それをDBに割り当てます!

docker volume create todo_pgdata

PostgreSQL 18+ は /var/lib/postgresql にマウントするのが推奨(ここが最新版の注意点)(hub.docker.com)

docker rm -f pg-good 2>/dev/null || true

docker run -d --name pg-good \
-e POSTGRES_PASSWORD=pass1234 \
--mount type=volume,src=todo_pgdata,dst=/var/lib/postgresql \
postgres:18

同じくテーブル作って1件入れます:

docker exec -it pg-good psql -U postgres -c \
"CREATE TABLE IF NOT EXISTS todos(id serial PRIMARY KEY, title text);
INSERT INTO todos(title) VALUES ('I will survive');
SELECT * FROM todos;"

コンテナを消します(でもVolumeは残る!)✨

docker rm -f pg-good

同じVolumeを付けて作り直す:

docker run -d --name pg-good \
-e POSTGRES_PASSWORD=pass1234 \
--mount type=volume,src=todo_pgdata,dst=/var/lib/postgresql \
postgres:18

確認:

docker exec -it pg-good psql -U postgres -c "SELECT * FROM todos;"

🎉 残ってたら勝ち! 🏆🥳 これが「DBはVolumeで守る」の基本です🧱🛡️


Step 3:Volumeってどこにあるの?👀

Docker的にはこう見えます:

docker volume inspect todo_pgdata

Mountpoint/var/lib/docker/volumes/.../_data みたいに出ます(Docker管理領域)(Docker Documentation) また、Docker DesktopはLinux VM上で動いていて、ファイル共有の仕組みが別レイヤーになります(Docker Documentation)

💡Windowsで「どこにあるの!?」ってなりがちだけど、 基本は “Dockerに任せる(= 直接いじらない)” が安全です🙂 どうしても見るなら \\wsl$ 配下に見えることがあります(Docker Desktopの更新で場所が変わることも)(JosephGuadagno.net)


5) Windows + Docker Desktopでの“強い運用ルール”🪟💪✨

ルールA:DBデータは Named Volume が安定🧱

特にWindowsは、VM越しのファイル共有が絡むので、 “Windows側フォルダをDBにbind mount”はトラブル(遅い・権限系)になりやすいです😵‍💫 Docker公式ブログでも「Named volumeはVM内で速い」と説明されています(Docker)

ルールB:bind mountするなら “Linux側ファイルシステム” に置く🐧⚡

WSL2を使うときは、bind mount対象は Windows側よりLinux側に置くのが推奨(速い&イベントも安定)(Docker Documentation)


6) よくある事故集(ここで泣く人が多い😭🧯)

❌ 事故1:PostgreSQLの“マウント先”を間違える

  • PostgreSQL 18+:/var/lib/postgresql にマウントが推奨(PGDATAがバージョン付きになった)(hub.docker.com)
  • PostgreSQL 17以下:/var/lib/postgresql/data にマウント推奨(逆に /var/lib/postgresql だと永続化されない注意)(hub.docker.com)

👉 対策:公式の注意書きを信じるイメージの説明を読む(これが一番堅い)🧠✨


❌ 事故2:bind mountで「元から入ってたデータ」が見えなくなる

bind mountは、コンテナ側の既存ファイルを上書きで隠す動きになります🫥 (マウントした瞬間、そのディレクトリの元の中身が“見えなくなる”)(Docker Documentation)

👉 対策:DBの保存先にbind mountする時は特に慎重に⚠️(基本はVolumeでOK)


❌ 事故3:「消えた!」と思ったら匿名ボリュームが残ってた

匿名ボリュームは 残るけど再利用されないことがあるので、 「新しいコンテナ作ったら空だった」になりやすいです🪤😇(Docker Documentation)

👉 対策:最初からNamed Volumeを作る(今回の todo_pgdata 方式)🧱✨


7) AI活用コーナー🤖✨(この章の“賢い使い方”)

🧠プロンプト1:データ仕分けテンプレを作らせる📋

「Todo APIで扱うデータを、永続/再生成/一時に分類して、保存方法(Volume/コンテナ内/bind mount)も提案して。テーブル形式で。初心者向けに。」

🧠プロンプト2:自分用“永続化チートシート”を作らせる📌

「DockerでDBを永続化する最小コマンド集を、Windows+WSL2前提で、事故りやすい点つきでまとめて。」

🧠プロンプト3:ログやエラーを貼って“次の一手”を聞く🧯

「このエラーの原因候補トップ3と、確認コマンドを順番に教えて:(エラー貼り付け)」


まとめ🏁🎉

  • DBデータはVolumeで守る🧱🛡️(コンテナは消してOK🙆‍♂️)(Docker Documentation)
  • Windows + Docker DesktopはVM越しなので、DBをWindowsパスbind mountは事故りやすい😵(基本Volume)(Docker)
  • PostgreSQLは特に バージョンでマウント先が変わるので公式注意を守る!(hub.docker.com)

ミニ確認クイズ🎓📝(3問)

  1. コンテナを rm したら、コンテナ内のDBファイルはどうなる?🗑️
  2. DBの永続化に基本おすすめなのは、Volume / bind mount どっち?🧱📁
  3. PostgreSQL 18+ で、永続化マウント先として推奨されるのはどこ?🐘

答え(サクッと)👇

  1. 消える(同じコンテナを残して start なら残るけど、作り直すと別物)
  2. Volume
  3. /var/lib/postgresql (hub.docker.com)

次の第18章は、**「開発データを気軽に作り直せる」seed運用🌱⚡**に進みます!