Docker + K8s CI/CD 自動化流水線

到目前為止,我們學會了 Docker 容器化、Docker Compose、Kubernetes 部署與監控。但每次更新版本時,如果都要手動執行 docker builddocker pushkubectl apply,不僅麻煩而且容易出錯。

CI/CD (Continuous Integration / Continuous Deployment) 就是為了解決這個問題而生。它讓你的部署流程完全自動化:

  1. 開發者推送程式碼到 GitHub
  2. 自動觸發建置流程
  3. 自動執行測試
  4. 自動建置 Docker Image 並推送到 Container Registry
  5. 自動更新 Kubernetes 叢集上的部署

整個過程完全不需要人工介入!

CI/CD 架構總覽

開發者推送程式碼到 GitHub
        │
        ▼
GitHub Actions 自動觸發
        │
        ├── 1. Checkout 程式碼
        ├── 2. 執行 ESLint / 單元測試
        ├── 3. 建置 Docker Image
        ├── 4. 推送 Image 到 Container Registry (Docker Hub / GHCR)
        ├── 5. 更新 Kubernetes 部署 YAML 中的 Image Tag
        └── 6. kubectl apply 部署到 K8s 叢集
        │
        ▼
Kubernetes 自動滾動更新

第一步:建立 Container Registry

Container Registry 是存放 Docker Image 的地方,類似 GitHub 但專門存放容器映像檔。以下是常見的選擇:

| Registry | 價格 | 說明 | |----------|------|------| | Docker Hub | 免費 1 個私有 Repository | 最普及,但免費方案有限制 | | GitHub Container Registry (GHCR) | 免費、無限制 | 🏆 推薦,與 GitHub Actions 完美整合 | | Google Artifact Registry | 付費 | GCP 使用者專用 |

我們使用 GitHub Container Registry (GHCR),因為它完全免費且與 GitHub Actions 無縫整合。

手動推送一次 Image(測試)

# 建立 Image 並標記為 GHCR 格式
# 格式:ghcr.io/<你的 GitHub 帳號>/<Image 名稱>:<版本>
docker build -t ghcr.io/your-username/my-app:latest .

# 登入 GHCR
echo $GITHUB_TOKEN | docker login ghcr.io -u your-username --password-stdin

# 推送 Image
docker push ghcr.io/your-username/my-app:latest

第二步:建立 GitHub Actions Workflow

在專案中建立 .github/workflows/deploy.yml

name: Build & Deploy to K8s

on:
  push:
    branches:
      - main          # 只有推送到 main 分支才觸發
      - develop       # 推送到 develop 也觸發(但不部署到正式)

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}

jobs:
  # === Job 1:測試與建置 ===
  build:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write    # 需要寫入 GHCR 的權限

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Run linting
        run: npm run lint

      - name: Run tests
        run: npm test

      - name: Log in to GitHub Container Registry
        uses: docker/login-action@v3
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Build and push Docker image
        uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: |
            ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
            ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}

  # === Job 2:部署到 Kubernetes ===
  deploy:
    needs: build          # 等待 build Job 完成
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'  # 只在 main 分支部署

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Setup kubectl
        uses: azure/setup-kubectl@v4
        with:
          version: 'v1.28.3'

      - name: Configure K8s context
        uses: azure/k8s-set-context@v4
        with:
          kubeconfig: ${{ secrets.KUBECONFIG }}

      - name: Update image tag in deployment YAML
        run: |
          # 使用 sed 將 YAML 中的 Image Tag 更新為當前 Commit SHA
          sed -i "s|image:.*|image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}|" k8s/deployment.yaml

      - name: Deploy to Kubernetes
        run: |
          kubectl apply -f k8s/
          kubectl rollout status deployment/frontend --timeout=5m
          kubectl rollout status deployment/backend --timeout=5m

Workflow 解析

觸發條件 (on)

  • 只有當 maindevelop 分支有推送時才觸發
  • 你可以根據需求設定不同的觸發條件(例如只針對特定路徑的變動)

Job 1:build

  1. 檢出程式碼
  2. 安裝 Node.js 並快取套件
  3. 安裝相依套件 (npm ci)
  4. 執行 Lint 檢查
  5. 執行測試
  6. 登入 GHCR
  7. 建置 Docker Image 並推送(同時推送 latestcommit SHA 兩個標籤)

Job 2:deploy

  1. 等待 build 成功
  2. 設定 kubectl
  3. 設定 K8s 連線資訊(使用 KUBECONFIG Secret)
  4. 更新部署 YAML 中的 Image 版本
  5. 部署到 K8s 並監控滾動更新狀態

第三步:設定 GitHub Secrets

為了安全起見,我們不應該將 K8s 連線資訊直接寫在程式碼中。請到 GitHub Repository 的 Settings → Secrets and variables → Actions 新增以下 Secret:

| Secret 名稱 | 說明 | 取得方式 | |------------|------|---------| | KUBECONFIG | K8s 叢集的 kubeconfig 檔案內容 | 從你的 .kube/config 複製,或是從雲端服務商下載 |

取得 KUBECONFIG

# DigitalOcean
 doctl kubernetes cluster kubeconfig show my-cluster

# 或是直接查看本機的 kubeconfig
cat ~/.kube/config

# 複製內容後貼到 GitHub Secrets 中

⚠️ 安全提醒:Kubeconfig 包含了叢集的管理員憑證,請絕對不要將它提交到 GitHub Repository 中!一定要使用 GitHub Secrets。

第四步:進階 CI/CD 技巧

1. 多環境部署(Staging / Production)

你可以設定兩個 Workflow,分別部署到測試與正式環境:

on:
  push:
    branches:
      - develop    # 自動部署到 Staging
      - main       # 自動部署到 Production

在 Workflow 中根據分支名稱動態切換 K8s 設定檔。

2. Database Migration 自動化

在部署新版本之前,自動執行資料庫 Migration:

- name: Run database migration
  run: |
    kubectl exec deployment/backend -- alembic upgrade head

3. 自動 Rollback(部署失敗時)

如果滾動更新失敗,自動回滾到上一個版本:

- name: Deploy to Kubernetes
  run: |
    kubectl apply -f k8s/ || \
      (echo "Deployment failed, rolling back..." && \
       kubectl rollout undo deployment/frontend && \
       exit 1)

完整 CI/CD 流程實戰演練

現在,讓我們實際跑一遍完整的 CI/CD 流程:

本地端

# 1. 開發新功能
git checkout -b feature/new-api

# 2. 修改程式碼...

# 3. 提交並推送
git add .
git commit -m "feat: add new API endpoint"
git push origin feature/new-api

GitHub Actions 自動執行

推送後,前往 GitHub Repository 的 Actions 頁面,你會看到一個新的 Workflow 正在執行。點擊進入可以看到即時的執行日誌。

驗證部署

# 當 Workflow 完成後,檢查 K8s 部署狀態
kubectl get pods
kubectl rollout status deployment/frontend

# 檢查新版本是否正確運行
kubectl logs -f -l app=frontend

使用 Vibe Coding 生成 CI/CD Workflow

不用背 YAML 語法!讓 AI 幫你產生:

**🔥 【CI/CD Workflow 詠唱範例】 ** 「請幫我產生一個 GitHub Actions Workflow: 1. 當推送到 main 或 develop 分支時觸發。 2. 使用 Node.js 20 進行 npm ci、lint 與 test。 3. 建置 Docker Image 並推送到 ghcr.io。 4. 使用 Image Tag 為 github.sha 與 latest。 5. 使用 kubectl 部署到 K8s,kubeconfig 從 GitHub Secrets 讀取。 6. 部署前先更新 deployment YAML 中的 Image Tag。 7. 部署後執行 kubectl rollout status 等待部署完成。 8. 加上超時設定與錯誤處理 (rollback)。」

本日總結

在本章中,你學到了:

  1. CI/CD 核心概念:從程式碼提交到自動部署的完整流程
  2. Container Registry:使用 GHCR 免費存放 Docker Image
  3. GitHub Actions Workflow:完整的 build → push → deploy 流水線
  4. GitHub Secrets:安全地管理 K8s 連線資訊
  5. 多環境部署:Staging / Production 分離
  6. 自動 Rollback:部署失敗時自動復原
  7. Vibe Coding 生成技巧:用自然語言描述 CI/CD 需求

恭喜你完成了整個 Docker & Kubernetes 雲端部署實戰 課程!你現在已經具備了將任何應用容器化、部署到雲端 K8s 叢集、設定監控與自動伸縮、以及建立自動化 CI/CD 流水線的完整能力。

這些技能在市場上具有極高的價值,無論是提升接案報價、求職 DevOps 工程師,或是經營自己的 SaaS 產品,都能讓你擁有巨大的競爭優勢!

解鎖完整教學內容

本章為付費內容。加入專案即可解鎖超過 5000 字的深度解析,包含 10 個以上神級 Prompt 與真實 Source Code 範例!