Docker 與容器化:為什麼不用 VM?
VM vs Container
VM(虛擬機器):
┌─────────────────┐
│ Your App │
│ Libraries │
│ Guest OS (整個作業系統) │ ← 幾 GB
│ Hypervisor │
│ Host OS │
│ Hardware │
└─────────────────┘
啟動:分鐘級
Container(容器):
┌─────────────────┐
│ Your App │
│ Libraries │ ← 幾十 MB
│ Container Engine (Docker) │
│ Host OS │
│ Hardware │
└─────────────────┘
啟動:秒級
| VM | Container | |
|---|---|---|
| 大小 | GB 級 | MB 級 |
| 啟動 | 分鐘 | 秒 |
| 隔離性 | 完全隔離(各自有 OS) | 共享 Host OS kernel |
| 效能 | 有虛擬化開銷 | 接近原生效能 |
| 適合 | 需要不同 OS | 同一 OS 上跑多個應用 |
Docker 解決什麼問題?
"在我的電腦上可以跑啊!"
↓
Docker:不管在誰的電腦上,環境都一樣
開發環境:macOS + .NET 8 + PostgreSQL 15
測試環境:Ubuntu + .NET 8 + PostgreSQL 15
正式環境:Ubuntu + .NET 8 + PostgreSQL 15
↓
全部用同一個 Docker Image → 環境完全一致
Image vs Container
Image(映像檔)= 模板(類似 class)
→ 唯讀的
→ 用 Dockerfile 建立
→ 可以分享到 Docker Hub
Container(容器)= 執行中的實例(類似 object)
→ 從 Image 建立
→ 可以有多個 Container 用同一個 Image
→ 有自己的檔案系統和網路
Layer(分層)
FROM mcr.microsoft.com/dotnet/aspnet:8.0 ← Layer 1(基礎)
COPY ./publish /app ← Layer 2(你的程式)
WORKDIR /app ← Layer 3(設定)
ENTRYPOINT ["dotnet", "MyApp.dll"] ← Layer 4(啟動指令)
每層都會被快取:
- 如果 Layer 1 沒變 → 直接用快取
- 只有改動的 Layer 會重新建立
- 所以 Dockerfile 要把不常改的放上面,常改的放下面
什麼時候不需要 Docker?
- 個人開發的小專案(直接跑就好)
- 學習階段(先學會跑,再學容器)
- 已經用 PaaS(Azure App Service 已經處理環境了)
- 團隊只有你一個人(沒有環境不一致的問題)
你的 DevLearn 部署到 Azure App Service,不需要 Docker。Azure 已經處理了環境問題。如果未來要用 Kubernetes 或多容器部署才需要。