Docker Deploy 教學:容器化部署從入門到實戰
「在我的電腦上可以跑啊!」——這句話曾經是開發者最常見的藉口。Docker 的出現,徹底解決了開發環境與生產環境不一致的問題。
透過容器化技術,你可以將應用程式連同所有相依套件打包成一個可攜式的「容器」,無論在哪個環境執行,行為都完全一致。這篇教學將帶你從零開始學習 Docker,從基礎概念到實際部署,讓你的應用程式真正做到「Build once, run anywhere」。
如果你想了解更完整的部署策略,可以先閱讀 程式部署完整指南。
Docker 基礎概念

插圖:容器 vs 虛擬機架構比較圖
場景描述:
Technical illustration showing 容器 vs 虛擬機架構比較圖. Clean, professional diagram style.
視覺重點:
- Clear presentation of the concept
- Professional technical diagram style
- Easy to understand visual elements
必須出現的元素:
- Relevant technical components
- Clear labels and annotations
- Logical flow or structure
需要顯示的中文字:
無
風格:
Clean flat design, technical illustration, modern infographic style
顏色調性:
Professional blues and grays, with accent colors for emphasis
避免元素:
Cluttered design, realistic photos, complex 3D rendering
在深入 Docker 操作之前,先建立正確的概念會讓後續的學習更加順暢。
什麼是 Docker?
Docker 是一個開源的容器化平台,讓你可以將應用程式及其所有相依項(程式碼、Runtime、系統工具、函式庫)打包成一個標準化的單元——容器(Container)。
容器的核心價值:
| 特性 | 說明 |
|---|---|
| 一致性 | 開發、測試、生產環境完全相同 |
| 隔離性 | 每個容器獨立運行,互不干擾 |
| 可攜性 | 在任何支援 Docker 的環境都能執行 |
| 輕量化 | 共享 Host OS 核心,資源佔用極低 |
| 快速啟動 | 秒級啟動,遠快於虛擬機的分鐘級 |
容器 vs 虛擬機
很多人會將容器與虛擬機(VM)搞混,但兩者的架構完全不同:
虛擬機(VM):
應用程式 A 應用程式 B 應用程式 C
Guest OS Guest OS Guest OS
↓ ↓ ↓
Hypervisor (VMware/VirtualBox)
↓
Host OS
↓
硬體
容器(Container):
應用程式 A 應用程式 B 應用程式 C
↓ ↓ ↓
Docker Engine
↓
Host OS
↓
硬體
主要差異比較:
| 項目 | 虛擬機 | 容器 |
|---|---|---|
| 啟動時間 | 數分鐘 | 數秒 |
| 硬碟佔用 | GB 級 | MB 級 |
| 記憶體佔用 | GB 級 | MB 級 |
| 隔離程度 | 完全隔離(有獨立 OS) | 程序級隔離(共享 Kernel) |
| 效能損耗 | 較高(需模擬硬體) | 極低(原生執行) |
容器適合部署應用程式,虛擬機適合需要完全隔離或不同作業系統的場景。
Docker 核心元件(Image、Container、Registry)

插圖:Docker 核心元件關係圖
場景描述:
Technical illustration showing Docker 核心元件關係圖. Clean, professional diagram style.
視覺重點:
- Clear presentation of the concept
- Professional technical diagram style
- Easy to understand visual elements
必須出現的元素:
- Relevant technical components
- Clear labels and annotations
- Logical flow or structure
需要顯示的中文字:
無
風格:
Clean flat design, technical illustration, modern infographic style
顏色調性:
Professional blues and grays, with accent colors for emphasis
避免元素:
Cluttered design, realistic photos, complex 3D rendering
理解這三個核心元件的關係,是掌握 Docker 的關鍵:
Image(映像檔)
- 唯讀的模板,包含執行應用程式所需的一切
- 類似於「程式的安裝檔」或「系統的快照」
- 由多個唯讀層(Layer)堆疊而成
Container(容器)
- Image 的運行實例
- 在 Image 之上加一個可寫層
- 類似於「從安裝檔執行起來的程式」
Registry(倉庫)
- 存放 Image 的地方
- 公開:Docker Hub、GitHub Container Registry
- 私有:AWS ECR、GCP Artifact Registry、Harbor
它們的關係可以用這個流程理解:
Dockerfile → (docker build) → Image → (docker push) → Registry
↓
(docker run)
↓
Container
Dockerfile 撰寫教學

插圖:Dockerfile 結構解析圖
場景描述:
Technical illustration showing Dockerfile 結構解析圖. Clean, professional diagram style.
視覺重點:
- Clear presentation of the concept
- Professional technical diagram style
- Easy to understand visual elements
必須出現的元素:
- Relevant technical components
- Clear labels and annotations
- Logical flow or structure
需要顯示的中文字:
無
風格:
Clean flat design, technical illustration, modern infographic style
顏色調性:
Professional blues and grays, with accent colors for emphasis
避免元素:
Cluttered design, realistic photos, complex 3D rendering
Dockerfile 是一個文字檔,定義了如何建構 Docker Image。每一行指令都會產生一個新的「層(Layer)」。
Dockerfile 基本結構
一個典型的 Dockerfile 結構如下:
# 1. 選擇基底映像
FROM node:20-alpine
# 2. 設定工作目錄
WORKDIR /app
# 3. 複製相依套件定義檔
COPY package*.json ./
# 4. 安裝相依套件
RUN npm ci --only=production
# 5. 複製應用程式程式碼
COPY . .
# 6. 開放 port
EXPOSE 3000
# 7. 設定啟動命令
CMD ["node", "server.js"]
為什麼要分開複製 package.json 和程式碼?
Docker 會快取每一層。如果程式碼改變但 package.json 沒變,npm install 的快取就能被重用,大幅加速建構時間。
常用指令(FROM、RUN、COPY、CMD)
| 指令 | 用途 | 範例 |
|---|---|---|
| FROM | 指定基底映像 | FROM node:20-alpine |
| WORKDIR | 設定工作目錄 | WORKDIR /app |
| COPY | 複製檔案到映像 | COPY . . |
| ADD | 複製檔案(支援 URL 與解壓縮) | ADD app.tar.gz /app |
| RUN | 在建構時執行命令 | RUN npm install |
| CMD | 容器啟動時執行的命令 | CMD ["node", "app.js"] |
| ENTRYPOINT | 容器啟動時執行的命令(不易被覆蓋) | ENTRYPOINT ["npm", "start"] |
| ENV | 設定環境變數 | ENV NODE_ENV=production |
| EXPOSE | 宣告開放的 port | EXPOSE 3000 |
| ARG | 建構時的變數 | ARG VERSION=1.0 |
CMD vs ENTRYPOINT:
- CMD:可以被 docker run 的參數覆蓋
- ENTRYPOINT:固定的執行命令,CMD 變成它的參數
# CMD 可被覆蓋
CMD ["npm", "start"]
# docker run myapp npm test → 執行 npm test
# ENTRYPOINT 不易覆蓋
ENTRYPOINT ["npm"]
CMD ["start"]
# docker run myapp test → 執行 npm test
多階段建置(Multi-stage Build)

插圖:Multi-stage Build 示意圖
場景描述:
Technical illustration showing Multi-stage Build 示意圖. Clean, professional diagram style.
視覺重點:
- Clear presentation of the concept
- Professional technical diagram style
- Easy to understand visual elements
必須出現的元素:
- Relevant technical components
- Clear labels and annotations
- Logical flow or structure
需要顯示的中文字:
無
風格:
Clean flat design, technical illustration, modern infographic style
顏色調性:
Professional blues and grays, with accent colors for emphasis
避免元素:
Cluttered design, realistic photos, complex 3D rendering
多階段建置是縮小 Image 大小的關鍵技巧。開發時需要編譯工具,但生產環境只需要編譯後的產物。
Node.js 多階段建置範例:
# 階段一:建置階段
FROM node:20 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# 階段二:生產階段
FROM node:20-alpine AS production
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY package*.json ./
EXPOSE 3000
CMD ["node", "dist/server.js"]
Go 語言多階段建置範例:
# 階段一:編譯
FROM golang:1.21 AS builder
WORKDIR /app
COPY go.* ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o main .
# 階段二:最小化執行環境
FROM alpine:3.18
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /app/main .
CMD ["./main"]
這個 Go 範例的最終 Image 只有約 15MB,而非編譯階段的數百 MB。
💡 Dockerfile 寫不出來?
容器化看似簡單,但要寫出安全、高效的 Dockerfile 需要經驗。
預約免費諮詢,讓我們幫你處理應用程式容器化。
Docker 部署實戰
學會撰寫 Dockerfile 後,接下來是實際的建構與部署流程。
建置 Docker Image
在 Dockerfile 所在目錄執行:
# 基本建置
docker build -t my-app:1.0.0 .
# 指定 Dockerfile 路徑
docker build -t my-app:1.0.0 -f Dockerfile.prod .
# 傳入建構參數
docker build -t my-app:1.0.0 --build-arg VERSION=1.0.0 .
# 不使用快取(完整重建)
docker build -t my-app:1.0.0 --no-cache .
建置選項說明:
| 選項 | 說明 |
|---|---|
-t name:tag |
指定 Image 名稱與標籤 |
-f Dockerfile |
指定 Dockerfile 路徑 |
--build-arg KEY=VALUE |
傳入 ARG 變數 |
--no-cache |
不使用快取 |
--platform linux/amd64 |
指定目標平台(跨架構建置) |
查看建置完成的 Image:
# 列出本地 Image
docker images
# 查看 Image 詳細資訊
docker inspect my-app:1.0.0
# 查看 Image 的層結構
docker history my-app:1.0.0
執行 Container
# 基本執行
docker run my-app:1.0.0
# 背景執行並開放 port
docker run -d -p 3000:3000 --name my-app my-app:1.0.0
# 傳入環境變數
docker run -d -p 3000:3000 \
-e NODE_ENV=production \
-e DATABASE_URL=postgres://... \
my-app:1.0.0
# 掛載 Volume
docker run -d -p 3000:3000 \
-v $(pwd)/data:/app/data \
my-app:1.0.0
執行選項說明:
| 選項 | 說明 |
|---|---|
-d |
Detached mode(背景執行) |
-p 主機:容器 |
Port mapping |
--name |
指定容器名稱 |
-e KEY=VALUE |
設定環境變數 |
-v 主機:容器 |
掛載 Volume |
--rm |
容器停止後自動刪除 |
-it |
互動模式(進入容器 shell) |
常用管理指令:
# 查看執行中的容器
docker ps
# 查看所有容器(包含已停止)
docker ps -a
# 查看容器 log
docker logs my-app
docker logs -f my-app # 持續追蹤
# 進入容器 shell
docker exec -it my-app sh
# 停止容器
docker stop my-app
# 啟動已停止的容器
docker start my-app
# 刪除容器
docker rm my-app
推送到 Docker Hub
Docker Hub 是最常用的公開 Registry,免費帳戶可以有一個私有 Repository。
# 1. 登入 Docker Hub
docker login
# 2. 為 Image 加上 Docker Hub 的標籤
docker tag my-app:1.0.0 username/my-app:1.0.0
# 3. 推送到 Docker Hub
docker push username/my-app:1.0.0
# 4. 其他機器就能拉取使用
docker pull username/my-app:1.0.0
如果使用私有 Registry(如 AWS ECR):
# AWS ECR 登入
aws ecr get-login-password --region ap-northeast-1 | \
docker login --username AWS --password-stdin 123456789.dkr.ecr.ap-northeast-1.amazonaws.com
# 推送到 ECR
docker tag my-app:1.0.0 123456789.dkr.ecr.ap-northeast-1.amazonaws.com/my-app:1.0.0
docker push 123456789.dkr.ecr.ap-northeast-1.amazonaws.com/my-app:1.0.0
部署到雲端平台
將容器化的應用程式部署到雲端,最常見的選擇:
| 平台 | 特點 | 適用場景 |
|---|---|---|
| GCP Cloud Run | Serverless 容器,按請求計費 | API、微服務 |
| AWS ECS/Fargate | 完整的容器編排服務 | 中大型應用 |
| Azure Container Apps | Serverless 容器,類似 Cloud Run | .NET 應用 |
| Railway | 簡單部署,Heroku 替代品 | Side Project |
以 GCP Cloud Run 為例:
# 建置並推送到 Google Container Registry
gcloud builds submit --tag gcr.io/PROJECT_ID/my-app:1.0.0
# 部署到 Cloud Run
gcloud run deploy my-app \
--image gcr.io/PROJECT_ID/my-app:1.0.0 \
--platform managed \
--region asia-east1 \
--allow-unauthenticated
想了解更多 GCP 部署方式,可以參考 GCP 部署指南。
Docker Compose 多容器部署

插圖:Docker Compose 多服務架構圖
場景描述:
Technical illustration showing Docker Compose 多服務架構圖. Clean, professional diagram style.
視覺重點:
- Clear presentation of the concept
- Professional technical diagram style
- Easy to understand visual elements
必須出現的元素:
- Relevant technical components
- Clear labels and annotations
- Logical flow or structure
需要顯示的中文字:
無
風格:
Clean flat design, technical illustration, modern infographic style
顏色調性:
Professional blues and grays, with accent colors for emphasis
避免元素:
Cluttered design, realistic photos, complex 3D rendering
當應用程式需要多個服務(如 Web Server + Database + Cache),Docker Compose 讓你用一個 YAML 檔案管理所有容器。
docker-compose.yml 撰寫
version: '3.8'
services:
web:
build: ./frontend
ports:
- "3000:3000"
environment:
- API_URL=http://api:8080
depends_on:
- api
api:
build: ./backend
ports:
- "8080:8080"
environment:
- DATABASE_URL=postgres://user:password@db:5432/myapp
- REDIS_URL=redis://cache:6379
depends_on:
- db
- cache
db:
image: postgres:15-alpine
environment:
- POSTGRES_USER=user
- POSTGRES_PASSWORD=password
- POSTGRES_DB=myapp
volumes:
- postgres_data:/var/lib/postgresql/data
cache:
image: redis:7-alpine
volumes:
- redis_data:/data
volumes:
postgres_data:
redis_data:
多服務編排
Docker Compose 的常用指令:
# 啟動所有服務(背景執行)
docker-compose up -d
# 查看服務狀態
docker-compose ps
# 查看服務 log
docker-compose logs api
docker-compose logs -f # 追蹤所有服務
# 重新建置並啟動
docker-compose up -d --build
# 停止所有服務
docker-compose down
# 停止並刪除 Volume
docker-compose down -v
擴展服務實例:
# 將 api 服務擴展為 3 個實例
docker-compose up -d --scale api=3
網路與 Volume 設定
網路設定:
Docker Compose 會自動建立一個網路,所有服務都能透過「服務名稱」互相存取。
services:
api:
networks:
- frontend
- backend
db:
networks:
- backend # db 只在 backend 網路,無法被 web 直接存取
networks:
frontend:
backend:
Volume 設定:
services:
db:
volumes:
# Named Volume(Docker 管理)
- postgres_data:/var/lib/postgresql/data
# Bind Mount(掛載本地目錄)
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
volumes:
postgres_data:
driver: local
| 類型 | 語法 | 用途 |
|---|---|---|
| Named Volume | volume_name:/path |
持久化資料(資料庫) |
| Bind Mount | ./local:/container |
開發時同步程式碼 |
| tmpfs | tmpfs:/path |
暫存資料(不持久化) |
💡 多容器架構太複雜?
微服務架構的容器編排、網路設定、資料持久化都需要謹慎規劃。
預約免費諮詢,讓專家幫你設計最佳的容器架構。
Docker 部署最佳實踐
掌握以下最佳實踐,讓你的 Docker 部署更加安全、高效。
Image 最小化
縮小 Image 大小可以加速部署、節省儲存成本:
1. 選擇精簡的基底映像
# 不推薦:完整 Ubuntu(約 77MB)
FROM ubuntu:22.04
# 推薦:Alpine(約 5MB)
FROM node:20-alpine
# 更推薦:Distroless(只有 Runtime)
FROM gcr.io/distroless/nodejs:20
2. 使用 .dockerignore
# .dockerignore
node_modules
.git
.env
*.log
Dockerfile
docker-compose.yml
README.md
3. 合併 RUN 指令減少層數
# 不推薦:多層
RUN apt-get update
RUN apt-get install -y curl
RUN apt-get clean
# 推薦:單層
RUN apt-get update && \
apt-get install -y curl && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
安全性考量
1. 不要以 root 執行
# 建立非 root 使用者
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
2. 不要在 Image 中存放敏感資訊
# 錯誤:密碼寫在 Dockerfile
ENV DATABASE_PASSWORD=secret123
# 正確:執行時傳入
# docker run -e DATABASE_PASSWORD=secret123 my-app
3. 掃描 Image 漏洞
# 使用 Docker Scout 掃描
docker scout cves my-app:1.0.0
# 使用 Trivy 掃描
trivy image my-app:1.0.0
4. 固定基底映像版本
# 不推薦:使用 latest
FROM node:latest
# 推薦:指定明確版本
FROM node:20.10.0-alpine3.18
日誌與監控
1. 輸出到 stdout/stderr
Docker 會自動收集寫到 stdout/stderr 的日誌:
// Node.js 範例
console.log('Application started'); // stdout
console.error('Error occurred'); // stderr
2. 查看容器日誌
# 查看最近 100 行
docker logs --tail 100 my-app
# 持續追蹤
docker logs -f my-app
# 加上時間戳記
docker logs -t my-app
3. 容器資源監控
# 即時資源使用狀況
docker stats
# 輸出範例:
# CONTAINER CPU % MEM USAGE / LIMIT MEM % NET I/O
# my-app 0.50% 128MiB / 512MiB 25% 1.5kB / 2.3kB
若需要進階監控,可以使用 Prometheus + Grafana,或雲端服務如 Datadog、New Relic。
如果你想將 Docker 容器部署到 Kubernetes 叢集,可以接著閱讀 Kubernetes Deploy 教學。
FAQ 常見問題
Q1: Docker Desktop 要收費嗎?
Docker Desktop 對於個人使用、小型企業(少於 250 員工且年營收低於 1000 萬美元)、教育機構是免費的。大型企業需要付費訂閱。
替代方案:
- macOS:可使用 Colima(免費)
- Windows:可使用 WSL2 + Docker Engine
- Linux:Docker Engine 本身是免費的
Q2: Image 太大怎麼辦?
- 使用 Alpine 或 Distroless 基底映像
- 使用 Multi-stage Build
- 清理不必要的檔案(cache、log、暫存檔)
- 使用 .dockerignore 排除不需要的檔案
Q3: Container 資料會消失嗎?
Container 停止或刪除後,內部的資料會消失。要持久化資料,必須使用 Volume:
docker run -v my-data:/app/data my-app
Q4: 開發環境如何同步程式碼?
使用 Bind Mount 將本地目錄掛載進容器:
services:
dev:
volumes:
- ./src:/app/src # 即時同步
搭配 nodemon 或 air 等工具實現 Hot Reload。
Q5: 如何連線到容器內的資料庫?
容器預設在獨立網路,要從本機連線需要 Port Mapping:
docker run -d -p 5432:5432 postgres:15
# 本機可用 localhost:5432 連線
結語
Docker 容器化是現代軟體開發與部署的基礎技能。這篇教學涵蓋了:
- 核心概念:Image、Container、Registry 的關係
- Dockerfile 撰寫:基本結構到多階段建置
- 部署實戰:從本地執行到推送雲端
- Docker Compose:多容器編排管理
- 最佳實踐:Image 最小化、安全性、日誌監控
掌握 Docker 後,你可以進一步學習 Kubernetes 來管理大規模的容器叢集。想了解更多,請參考 Kubernetes Deploy 教學。
🐳 容器化部署需要協助?
從 Dockerfile 撰寫到生產環境最佳化,Docker 有許多細節需要注意。
預約免費諮詢,讓 VibeFix 的工程師幫你規劃完整的容器化部署方案。