cover

Infra Core + CI/CD:讓部署變成可靠的流程

「能部署」與「能穩定交付」是兩件事。Infra Core 的目標是建立一套可重複、可追蹤、可回滾的交付流程,避免每次部署都靠「手動操作與祈禱」。

當交付流程沒有標準化,你會遇到:

  • 不同專案用不同流程,接手成本高
  • 部署失敗後沒有記錄,不知道發生什麼
  • 回滾需要重 build,耗時且高風險

架構概覽

flowchart LR
  Dev[Developer] --> Git[Git Repo]
  Git --> CI[CI Pipeline]
  CI --> Build[Build Image]
  Build --> Registry[Container Registry]
  Registry --> Deploy[CD Deploy]
  Deploy --> App[Production]
  Deploy --> Rollback[Rollback Plan]

核心概念

  1. 版本化與可追溯

    • 每次部署都對應到一個 commit 或 tag。
    • 遇到問題能快速定位「哪次部署造成」。
    • 重點:部署紀錄要可追蹤到人與變更內容。
  2. Pipeline 分段與標準化

    • 建置、測試、掃描、部署都應該是 pipeline 的不同階段。
    • 不同專案共享同一套模板與規範。
    • 好處:降低人員流動造成的知識落差。
  3. Artifact 與 Image 管理

    • Build 的輸出要可重複下載(artifact 或 image)。
    • 沒有 artifact,回滾只能重 build,風險高。
    • 建議:保留最近 N 版 image,並標記 release。
  4. 部署策略(Rolling / Blue-Green / Canary)

    • 依系統等級與風險選用不同策略。
    • 重點是可控與可回退。
    • 提醒:不同策略要有不同監控與驗收條件。
  5. 稽核與記錄

    • 每次部署都應該有紀錄:誰部署、何時部署、部署什麼。
    • 結合 ChatOps 可以提升可視性。
    • 目標:部署紀錄可被查詢、可被還原。

使用情境(具體場景)

  • 小團隊交付:只要 push 就自動跑測試與部署,降低人為錯誤。
  • 大版本上線:透過 Canary 先放 5% 流量,觀察穩定再擴大。
  • 緊急回滾:一鍵回退到上一版 image,減少停機。
  • 多服務協作:共同使用 pipeline 模板,確保流程一致。

實作範例 / 設定範例

1) GitLab CI 基礎 Pipeline

stages:
  - test
  - build
  - deploy
 
unit-test:
  stage: test
  image: node:20
  script:
    - npm ci
    - npm run test
 
build-image:
  stage: build
  image: docker:24
  services:
    - docker:24-dind
  script:
    - docker build -t registry.example.com/api:$CI_COMMIT_SHA .
    - docker push registry.example.com/api:$CI_COMMIT_SHA
 
deploy-prod:
  stage: deploy
  script:
    - ssh ops@prod "docker pull registry.example.com/api:$CI_COMMIT_SHA"
    - ssh ops@prod "docker stop api && docker rm api"
    - ssh ops@prod "docker run -d --name api registry.example.com/api:$CI_COMMIT_SHA"
  when: manual

2) 部署策略:Blue-Green 切換

# 假設目前是 blue 版本
export ACTIVE=blue
export IDLE=green
 
# 部署到 idle
ssh ops@prod "docker run -d --name api-$IDLE registry.example.com/api:$CI_COMMIT_SHA"
 
# 切換 Nginx upstream
ssh ops@prod "sed -i 's/api-$ACTIVE/api-$IDLE/g' /etc/nginx/conf.d/api.conf && nginx -s reload"

3) Rollback 腳本(快速回復)

# rollback.sh
PREV_TAG=$(cat /opt/app/prev_tag)
ssh ops@prod "docker pull registry.example.com/api:$PREV_TAG"
ssh ops@prod "docker stop api && docker rm api"
ssh ops@prod "docker run -d --name api registry.example.com/api:$PREV_TAG"

4) 發佈記錄(Release Note 範例)

## Release 2024-09-15
- feat: 支援訂單批次匯出
- fix: 修正付款狀態同步延遲
- infra: 更新 API image 至 1.2.0

5) 部署變數清單(範例)

# deploy-vars.yaml
app:
  NODE_ENV: production
  LOG_LEVEL: info
  FEATURE_FLAG_EXPORT: "true"
 
infra:
  DATABASE_URL: "postgres://user:***@db.internal:5432/app"
  REDIS_URL: "redis://redis.internal:6379"

環境變數與部署治理

部署時的設定應該被視為「受控資產」,而不是散落在機器上的手動設定。 建議將環境變數集中管理,搭配最小權限與可稽核更新。

常見問題與風險

  • 部署不一致: 手動部署容易漏步驟或版本不一致。要用 pipeline 標準化。

    • 避免方式:用共用模板,把部署流程固定化。
  • 沒有回滾策略: 上線出問題只能硬修,增加停機時間。必須保留前一版 image。

    • 避免方式:在 registry 保留上一版標籤。
  • 沒有安全掃描: build 過程未檢查漏洞,可能把危險套件推進 production。建議加入 SAST/容器掃描。

    • 避免方式:pipeline 加入安全掃描 stage。
  • 部署權限混亂: 任何人都能 deploy 會有風險。部署權限應該有限制並可稽核。

    • 避免方式:透過 RBAC 與審核流程控管。
  • 缺乏發布紀錄: 發生問題時無法快速找到變更內容。需要 release note 或變更紀錄。

    • 避免方式:在 pipeline 中自動生成 release note。

優點

  • 部署可重複、可追溯
  • 發布流程標準化,降低人為錯誤
  • 支援快速回滾,降低事故影響

缺點 / 限制

  • 初期建置 CI/CD 成本高
  • pipeline 太嚴格可能降低部署效率
  • 若基礎設施不穩定,CI/CD 也會卡住

落地檢查清單

  • pipeline 是否標準化且有模板
  • 是否保存 artifact/image 可回滾
  • 是否有 deploy 權限控管
  • 是否有發布紀錄
  • 是否能支援灰度或 Blue-Green

延伸閱讀