今天我們要解決一個 Docker 新手常遇到的問題:
「為什麼我容器一刪,資料就全沒了?」
這篇會教你搞懂 Docker 為什麼資料會消失、什麼是 Volume、怎麼讓資料「活下來」。
昨天我們理解了 Docker Image 的分層機制。
今天要解決另一個超實際的問題——資料持久化。
當你用 Docker 跑應用程式(像 Todo API、MongoDB、PostgreSQL),
容器刪掉就連資料也一起拜拜。
這就是所謂的「容器是暫時的」。
因為容器的檔案系統是臨時的。
它在 Image 上面疊一層「可寫層(Writable Layer)」,
一旦容器被刪掉,那層也一起消失。
👉 所以我們需要一個辦法,讓資料存在容器外。
Docker 提供三種做法:
類型 | 用途 | 優點 |
---|---|---|
Volume | 儲存在 Docker 管理的路徑下(推薦) | 跨容器共享、安全、獨立於容器生命週期 |
Bind Mount | 掛載本機資料夾 | 方便開發,修改即時同步 |
Tmpfs Mount | 暫存在記憶體 | 高速但重啟就沒了 |
我們今天主要練習 Volume 和 Bind Mount。
先建立一個 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 不會再消失了。
如果你想要在容器中即時看到本機的程式變動,可以掛載整個目錄。
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,避免被覆蓋這樣你在本機改檔案、容器內的程式會即時反映。
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 處理的)。
指令 | 說明 |
---|---|
docker volume ls |
查看所有 volume |
docker volume rm <name> |
刪除特定 volume |
docker volume prune |
清掉沒被使用的 volume |
假設你的 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 裡。
未來如果你用 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 讓資料安全存下來。
收穫重點:
docker volume inspect
可以看到真實路徑以前我把容器想成一台「小電腦」,今天才真正理解它其實是「暫時存在的工作站」,
真正要保存的東西,得放在外面的硬碟(Volume)。