iT邦幫忙

2025 iThome 鐵人賽

1
自我挑戰組

《轉職學習日記:JavaScript × Node.js × TypeScript × Docker × AWS ECS》系列 第 31

Day31 - 持續成長學習藍圖 - Docker(資料持久化與 Volume)

  • 分享至 

  • xImage
  •  

今天我們要解決一個 Docker 新手常遇到的問題:

「為什麼我容器一刪,資料就全沒了?」

這篇會教你搞懂 Docker 為什麼資料會消失、什麼是 Volume、怎麼讓資料「活下來」。


Day 31:資料持久化與 Volume

昨天我們理解了 Docker Image 的分層機制。
今天要解決另一個超實際的問題——資料持久化

當你用 Docker 跑應用程式(像 Todo API、MongoDB、PostgreSQL),
容器刪掉就連資料也一起拜拜。
這就是所謂的「容器是暫時的」。


1️⃣ 為什麼容器重啟資料會消失?

因為容器的檔案系統是臨時的。
它在 Image 上面疊一層「可寫層(Writable Layer)」,
一旦容器被刪掉,那層也一起消失。

👉 所以我們需要一個辦法,讓資料存在容器外。

Docker 提供三種做法:

類型 用途 優點
Volume 儲存在 Docker 管理的路徑下(推薦) 跨容器共享、安全、獨立於容器生命週期
Bind Mount 掛載本機資料夾 方便開發,修改即時同步
Tmpfs Mount 暫存在記憶體 高速但重啟就沒了

我們今天主要練習 VolumeBind Mount


2️⃣ Volume 實戰(推薦用法)

先建立一個 Volume:

docker volume create todo_data

查看 Volume:

docker volume ls

然後我們執行容器,掛上這個 Volume:

docker run -d \
  --name ts-todo-vol \
  -p 3000:3000 \
  -v todo_data:/app/prisma \
  ts-todo-api:v2

這樣容器的 /app/prisma 目錄(例如 SQLite 檔案)
就會被永久保存到 Volume todo_data 裡。

刪除容器再重啟時,資料還在:

docker rm -f ts-todo-vol
docker run -d -p 3000:3000 -v todo_data:/app/prisma ts-todo-api:v2

🎉 你的 SQLite 或 Prisma DB 不會再消失了。


3️⃣ Bind Mount(開發時常用)

如果你想要在容器中即時看到本機的程式變動,可以掛載整個目錄。

docker run -d \
  --name ts-todo-dev \
  -p 3000:3000 \
  -v "$(pwd):/app" \
  -v /app/node_modules \
  ts-todo-api:v2

說明:

  • -v "$(pwd):/app" → 把目前目錄掛進容器
  • -v /app/node_modules → 保留容器自己的 node_modules,避免被覆蓋

這樣你在本機改檔案、容器內的程式會即時反映。


4️⃣ 查看 Volume 實際存放路徑

docker volume inspect todo_data

輸出類似:

[
  {
    "Name": "todo_data",
    "Mountpoint": "/var/lib/docker/volumes/todo_data/_data",
    "Driver": "local"
  }
]

也就是說,Docker 把資料放在 /var/lib/docker/volumes/... 下(這在 Mac/Windows 裡是由 Docker Desktop 處理的)。


5️⃣ Volume 清理與管理

指令 說明
docker volume ls 查看所有 volume
docker volume rm <name> 刪除特定 volume
docker volume prune 清掉沒被使用的 volume

6️⃣ 實作:Todo 資料不再消失

假設你的 Prisma 設定使用 SQLite(預設是 prisma/dev.db
在 Dockerfile 中你已經設定 WORKDIR /app
那我們就可以這樣啟動容器:

docker run -d \
  --name ts-todo-persist \
  -p 3000:3000 \
  -v todo_data:/app/prisma \
  ts-todo-api:v3

重點就是:

/app/prisma 掛上 volume。

這樣即使你刪掉容器、重建,
dev.db 仍然會存在 Volume 裡。


7️⃣ 延伸概念:多容器共享 Volume

未來如果你用 Docker Compose 跑「API + DB」兩個服務,
Volume 可以在它們之間共用。

例如:

volumes:
  db_data:
    driver: local

然後:

services:
  db:
    image: postgres
    volumes:
      - db_data:/var/lib/postgresql/data
  api:
    build: .
    volumes:
      - .:/app

這樣就能保留 DB 資料,即使重建整個環境也不怕。


🎯 今日收穫 / 學習心得

今天我終於弄懂為什麼 Docker 容器會「失憶」😅
也學會用 Volume 讓資料安全存下來。

收穫重點:

  • 容器刪掉 = 可寫層刪掉
  • Volume 是專門用來持久化資料的
  • Bind Mount 適合開發時即時更新
  • docker volume inspect 可以看到真實路徑

以前我把容器想成一台「小電腦」,今天才真正理解它其實是「暫時存在的工作站」,
真正要保存的東西,得放在外面的硬碟(Volume)。


上一篇
Day30 - 持續成長學習藍圖 - Docker(理解 Image 與 Build 機制)
下一篇
Day32 - 持續成長學習藍圖 - Docker(Docker Compose 入門)
系列文
《轉職學習日記:JavaScript × Node.js × TypeScript × Docker × AWS ECS》34
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言