開發者 Docker 指南:映像檔、容器與 Compose
你寫的程式碼在你的機器上可以正常運行,但當隊友嘗試執行時,卻遇到缺少相依套件、版本衝突或難以理解的錯誤。Docker 透過將應用程式及其環境打包成一個可攜式單元來解決這個問題。在本指南中,你將學習 Docker 的基礎知識:映像檔、容器與 Compose,並透過實際步驟將一個簡單的網頁應用程式容器化。
什麼是 Docker?
Docker 是一個用於建置、執行和分享容器化應用程式的平台。容器是一個輕量、獨立的可執行套件,包含執行軟體所需的一切:程式碼、執行環境、系統工具、函式庫和設定。容器將應用程式彼此隔離,也與主機系統隔離,確保在開發、測試和生產環境中的一致性。
映像檔 vs 容器:藍圖與執行實例
映像檔是一個唯讀範本,用於定義容器。它就像物件導向程式設計中的類別。容器是映像檔的可執行實例,就像物件。你可以從同一個映像檔建立多個容器。
映像檔是從 Dockerfile 建置而成,這是一個包含指令的純文字檔案。容器則透過 docker run 啟動。
主要差異
| 映像檔 | 容器 |
|---|---|
| 唯讀範本 | 可執行實例 |
使用 docker build 建置 | 使用 docker run 啟動 |
| 儲存在註冊表(例如 Docker Hub) | 在主機上執行 |
| 分層檔案系統 | 頂部可寫層 |
建置你的第一個映像檔
讓我們將一個簡單的 Node.js 應用程式容器化。建立一個名為 Dockerfile 的檔案:
# 使用官方 Node.js 執行環境作為父映像檔
FROM node:18-alpine
# 設定工作目錄
WORKDIR /app
# 複製 package.json 並安裝相依套件
COPY package*.json ./
RUN npm install
# 複製應用程式的其餘部分
COPY . .
# 暴露應用程式執行的連接埠
EXPOSE 3000
# 定義執行應用程式的指令
CMD ["node", "server.js"]
使用標籤建置映像檔:
docker build -t my-node-app .
-t 旗標為映像檔命名並加上標籤。最後的 . 指定建置上下文(目前目錄)。
執行容器
從你的映像檔啟動一個容器:
docker run -p 3000:3000 -d --name my-app my-node-app
-p 3000:3000:將主機的連接埠 3000 對應到容器的連接埠 3000。-d:以分離模式(在背景)執行容器。--name my-app:為容器指派名稱,方便參考。
使用 docker ps 檢查執行中的容器。使用 docker stop my-app 停止容器。
使用磁碟區管理資料
容器是短暫的;當容器被移除時,其中的資料也會遺失。若要保存資料,請使用磁碟區。例如,若要保存資料庫資料:
docker run -v my-db-data:/var/lib/mysql -d mysql:8
這會建立一個名為 my-db-data 的具名磁碟區,它會在容器重新啟動和移除後仍然存在。
使用 Docker Compose 簡化多容器應用程式
真實的應用程式通常需要多個服務:網頁伺服器、資料庫、快取等。Docker Compose 讓你用單一 YAML 檔案定義並執行多容器應用程式。
建立一個 docker-compose.yml:
version: '3.8'
services:
web:
build: .
ports:
- "3000:3000"
depends_on:
- db
environment:
- DATABASE_URL=postgres://user:pass@db:5432/mydb
db:
image: postgres:15
volumes:
- postgres_data:/var/lib/postgresql/data
environment:
- POSTGRES_USER=user
- POSTGRES_PASSWORD=pass
- POSTGRES_DB=mydb
volumes:
postgres_data:
使用以下指令執行所有服務:
docker compose up -d
Compose 會建置 web 映像檔、啟動資料庫,並將它們連接在共享網路上。depends_on 確保資料庫在 web 服務之前啟動。
必備 Docker 指令
docker ps -a:列出所有容器(包括已停止的)。docker images:列出映像檔。docker logs my-app:檢視容器日誌。docker exec -it my-app sh:在執行中的容器內開啟 shell。docker compose down:停止並移除 Compose 檔案中定義的容器、網路和磁碟區。
開發最佳實踐
- 使用 .dockerignore 從建置上下文中排除檔案(例如 node_modules),加速建置。
- 利用多階段建置 保持生產映像檔精簡。例如,在一個階段建置應用程式,然後只將必要的產物複製到精簡的執行環境映像檔中。
- 固定版本 在 Dockerfile 中(例如使用
node:18-alpine而非node:latest)以確保可重現性。 - 以非 root 使用者執行 以提升安全性。在複製檔案後加入
USER node。
常見問題
Docker 映像檔和容器有什麼區別?
映像檔是一個唯讀範本,定義應用程式及其環境。容器是該映像檔的執行實例。你可以從同一個映像檔建立多個容器。
如何在 Docker 中保存資料?
使用磁碟區。具名磁碟區(例如 docker run -v my-vol:/data)儲存在容器檔案系統之外,並在容器重新啟動和移除後仍然存在。
何時應該使用 Docker Compose?
當你的應用程式由多個需要一起執行的服務組成時(例如網頁 + 資料庫),請使用 Compose。它簡化了開發和測試的協調工作。
準備好將你的下一個專案容器化了嗎?從撰寫一個簡單的 Dockerfile 並執行你的第一個容器開始。如需更多開發者工具,請查看 TryQuickToolBox 的 JSON Formatter,在測試你的容器化服務時驗證 API 回應。