開發者 Docker 指南:映像、容器與 Compose
你是開發者,也聽過 Docker。也許你試過,但對於映像(image)、容器(container)和 Compose 的概念仍感到模糊。或者你已經受夠了「在我的機器上可以跑」,想要一個一致的環境。這份指南將撥開迷霧,讓你實際理解 Docker 的核心元件,並學會如何有效運用它們。
為什麼開發者該用 Docker?
Docker 解決了環境不一致的問題。與其直接在你的機器上安裝相依套件,不如將應用程式及其相依套件打包成容器。容器在任何地方都以相同方式運行:你的筆電、同事的筆電,以及生產環境。這消除了設定漂移,也讓新手快速上手。
映像:藍圖
映像是一個唯讀範本。它包含你的應用程式碼、執行環境、函式庫和環境變數。你可以從 Dockerfile 建置映像,這是一個包含指令的文字檔。
以下是 Node.js 應用程式的簡單 Dockerfile:
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]
每個指令都會建立一個層(layer)。層會被快取,因此當只有程式碼變更時,重新建置會很快。映像會儲存在如 Docker Hub 或私有登錄檔(registry)中。
容器:執行實例
容器是映像的可執行實例。它是隔離的,但共用主機作業系統核心,因此很輕量。你可以用 docker run 啟動容器。
docker run -p 3000:3000 -d my-app
這會將主機的 3000 埠對應到容器的 3000 埠,並以分離模式(detached mode)執行。容器是短暫的:除非使用 volume,否則移除後變更就會遺失。
常用指令:
docker ps– 列出執行中的容器docker stop <container>– 停止容器docker rm <container>– 移除容器docker images– 列出映像docker rmi <image>– 移除映像
Docker Compose:多容器應用程式
真實的應用程式通常需要多個服務:網頁伺服器、資料庫、快取。Docker Compose 讓你用單一 YAML 檔案定義並執行多容器應用程式。
以下是搭配 PostgreSQL 的 Node.js 應用程式的 docker-compose.yml:
version: '3.8'
services:
web:
build: .
ports:
- "3000:3000"
environment:
- DATABASE_URL=postgres://user:pass@db:5432/mydb
depends_on:
- db
db:
image: postgres:15
environment:
- POSTGRES_USER=user
- POSTGRES_PASSWORD=pass
- POSTGRES_DB=mydb
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:
執行 docker compose up 即可啟動兩個服務。Compose 會處理網路,因此 web 可以透過服務名稱連線到 db。
何時使用 Docker Compose 與純 Docker
| 情境 | 使用方式 |
|---|---|
| 單一容器 | docker run |
| 多個服務(應用程式 + 資料庫) | Docker Compose |
| 生產環境協調 | Kubernetes、Swarm |
開發者的最佳實踐
- 使用 .dockerignore 排除 node_modules、.git 等,加快建置速度。
- 多階段建置 讓最終映像保持精簡。
- 在 FROM 陳述式中固定版本,以確保可重現性。
- 不要在生產容器中以 root 身分執行。
- 使用 volume 來保存持久化資料,並在開發期間實現即時程式碼重載。
常見陷阱
連接埠衝突: 如果 3000 埠被佔用,請對應到不同的主機埠:-p 3001:3000。
資料遺失: 如果沒有 volume,容器移除時資料庫資料就會消失。
建置緩慢: 將 Dockerfile 指令從最少變更到最常變更的順序排列,以充分利用快取。
常見問題
映像和容器有什麼不同?
映像是一個唯讀範本;容器是該映像的執行實例。你可以從同一個映像執行多個容器。
單一服務需要 Docker Compose 嗎?
不需要。Compose 的優勢在於多個服務。對於單一容器,docker run 更簡單。
如何在 Docker 中保存資料?
使用 volume。在 Compose 中定義具名 volume,或使用 docker run 的 -v 來掛載主機目錄或具名 volume。
準備好簡化你的 Docker 工作流程了嗎?試試我們的 JSON Formatter,快速驗證並格式化如 docker-compose.yml 或 package.json 等 JSON 設定檔。