Docker Deploy 教學:容器化部署從入門到實戰【2025】

Docker Deploy 教學:容器化部署從入門到實戰

「在我的電腦上可以跑啊!」——這句話曾經是開發者最常見的藉口。Docker 的出現,徹底解決了開發環境與生產環境不一致的問題。

透過容器化技術,你可以將應用程式連同所有相依套件打包成一個可攜式的「容器」,無論在哪個環境執行,行為都完全一致。這篇教學將帶你從零開始學習 Docker,從基礎概念到實際部署,讓你的應用程式真正做到「Build once, run anywhere」。

如果你想了解更完整的部署策略,可以先閱讀 程式部署完整指南


Docker 基礎概念

container-vs-vm

插圖:容器 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-core-components

插圖: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-structure

插圖: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

插圖: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-architecture

插圖: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 太大怎麼辦?

  1. 使用 Alpine 或 Distroless 基底映像
  2. 使用 Multi-stage Build
  3. 清理不必要的檔案(cache、log、暫存檔)
  4. 使用 .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 的工程師幫你規劃完整的容器化部署方案。

分享文章:
V

VibeFix

專門解決 AI Vibe Coding 後的疑難雜症,讓你的專案順利上線。

這篇文章有幫到你嗎?

如果還有問題,讓我們直接幫你解決!

聯繫我們