GitLab 是企業級程式碼託管與 DevOps 平台,提供從程式碼管理到部署的完整生命週期解決方案。本章涵蓋 GitLab 的核心特色、CI/CD 組態以及 DevOps 實踐整合。


一、GitLab 與 GitHub 的差異#

為何企業偏好 GitLab#

在「自建託管(Self-managed)」的 Git 市場中,GitLab 佔據約 2/3 的份額。關鍵在於「資料掌控權」與「二次開發能力」。

面向GitHubGitLab
部署方式主要雲端託管支援自建與雲端
開源版本社群版(CE)免費開源
CI/CD依賴 Actions 或第三方內建完整 CI/CD
定價進階功能付費社群版功能豐富

GitLab 核心優勢#

  1. 開源生態與自主性

    • 社群版(CE)完全免費開源
    • 企業可基於 Ruby on Rails 進行二次開發
  2. 單一應用程式設計

    • 程式碼管理、CI/CD、專案協作整合於一套系統
    • 相較拼湊工具鏈,回應速度與效能更佳
  3. 全球社群維護

    • 超過 2000 名貢獻者
    • 持續迭代,功能不斷增強

二、GitLab DevOps 生命週期#

GitLab 將 DevOps 流程細分為多個階段:

Plan → Create → Verify → Package → Release → Configure → Monitor → Secure

各階段功能#

階段功能說明
PlanIssue、Board需求與任務管理
CreateRepository、MR程式碼管理與審查
VerifyCI Pipeline自動化測試與檢查
PackageContainer RegistryDocker 映像管理
ReleaseCD Pipeline自動化部署
ConfigureAuto DevOps環境組態管理
MonitorMetrics監控與告警
SecureSAST、DAST安全掃描

術語對照

  • GitHub 的 Pull Request (PR) = GitLab 的 Merge Request (MR)
  • 兩者本質相同,都是申請程式碼合併並觸發審查

三、GitLab CI/CD 組態#

核心組態檔案#

GitLab CI 的運作基礎是專案根目錄下的 .gitlab-ci.yml

# 定義執行階段
stages:
  - build
  - test
  - deploy

# 建置任務
build:
  stage: build
  script:
    - npm install
    - npm run build
  artifacts:
    paths:
      - dist/

# 測試任務
test:
  stage: test
  script:
    - npm run lint
    - npm test

# 部署任務(僅 main 分支)
deploy:
  stage: deploy
  script:
    - ./deploy.sh
  only:
    - main

Pipeline 與 Stage#

Pipeline
  ├── Stage: build (順序執行)
  │     └── Job: build
  ├── Stage: test (同階段可並行)
  │     ├── Job: lint
  │     ├── Job: unit-test
  │     └── Job: integration-test
  └── Stage: deploy (順序執行)
        └── Job: deploy-production

Pipeline 設計原則

  • 透過「順序執行」保證邏輯正確性
  • 透過「並行執行」最大化構建效率

常用組態選項#

# 指定 Docker 映像
image: node:20

# 快取依賴
cache:
  paths:
    - node_modules/

# 條件執行
only:
  - main
  - develop
except:
  - tags

# 手動觸發
when: manual

# 變數
variables:
  NODE_ENV: production

# 環境
environment:
  name: production
  url: https://example.com
完整範例:Node.js 專案 CI/CD
image: node:20

stages:
  - install
  - test
  - build
  - deploy

cache:
  key: ${CI_COMMIT_REF_SLUG}
  paths:
    - node_modules/

install:
  stage: install
  script:
    - npm ci

lint:
  stage: test
  script:
    - npm run lint

unit-test:
  stage: test
  script:
    - npm test
  coverage: '/All files[^|]*\|[^|]*\s+([\d\.]+)/'

build:
  stage: build
  script:
    - npm run build
  artifacts:
    paths:
      - dist/
    expire_in: 1 week

deploy-staging:
  stage: deploy
  script:
    - ./scripts/deploy.sh staging
  environment:
    name: staging
    url: https://staging.example.com
  only:
    - develop

deploy-production:
  stage: deploy
  script:
    - ./scripts/deploy.sh production
  environment:
    name: production
    url: https://example.com
  only:
    - main
  when: manual

四、GitLab Runner#

什麼是 Runner#

Runner 是執行 CI/CD 任務的「代理人」,負責:

  1. 接收 GitLab 伺服器的指令
  2. 執行構建與測試任務
  3. 回傳結果給 GitLab

如果沒有組態或啟動 Runner,即使 .gitlab-ci.yml 語法正確,Pipeline 也會處於 pending 狀態,無法執行。

Runner 類型#

類型說明適用場景
Shared RunnerGitLab.com 提供的公共 Runner一般專案、快速測試
Specific Runner自建伺服器安裝的 Runner特殊環境需求、私有部署
Group Runner群組層級共享的 Runner多專案共用

組態 Specific Runner#

# 1. 下載並安裝 GitLab Runner
curl -L --output /usr/local/bin/gitlab-runner \
  https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-amd64
chmod +x /usr/local/bin/gitlab-runner

# 2. 註冊 Runner
gitlab-runner register

# 3. 啟動 Runner
gitlab-runner run

註冊時需要:

  • GitLab URL(如 https://gitlab.com
  • Registration Token(在 Settings → CI/CD → Runners 取得)
  • Executor 類型(如 dockershell

五、分支保護與環境變數#

分支保護#

確保關鍵分支的安全性:

  1. 進入 Settings → Repository → Protected Branches
  2. 選擇要保護的分支(如 main
  3. 設定權限:
    • Allowed to merge: Maintainers
    • Allowed to push: No one(強制透過 MR)

CI/CD 變數#

儲存敏感資訊,避免寫入程式碼:

  1. 進入 Settings → CI/CD → Variables
  2. 新增變數:
    • DEPLOY_KEY:部署金鑰
    • AWS_ACCESS_KEY_ID:雲端憑證
    • DATABASE_URL:資料庫連線字串

勾選 Protected 確保變數僅在受保護分支可用;勾選 Masked 避免在日誌中顯示。


六、自動化部署實體#

部署到 AWS EC2#

stages:
  - test
  - deploy

variables:
  DEPLOY_SERVER: $AWS_EC2_HOST

test:
  stage: test
  script:
    - npm ci
    - npm run lint
    - npm test

deploy:
  stage: deploy
  before_script:
    # 設定 SSH 金鑰
    - mkdir -p ~/.ssh
    - echo "$PRIVATE_KEY" | tr -d '\r' > ~/.ssh/id_rsa
    - chmod 600 ~/.ssh/id_rsa
    - ssh-keyscan -H $DEPLOY_SERVER >> ~/.ssh/known_hosts
  script:
    - ssh ubuntu@$DEPLOY_SERVER "cd /app && git pull && npm install && pm2 restart app"
  only:
    - main
  environment:
    name: production
    url: https://example.com

部署流程說明#

Push to main
     ↓
Test Stage: lint + unit test
     ↓
Deploy Stage:
  1. 設定 SSH 連線
  2. SSH 到 AWS EC2
  3. git pull 更新程式碼
  4. npm install 安裝依賴
  5. pm2 restart 重啟服務
     ↓
部署完成

此範例適用於簡單的 Node.js 應用。對於複雜專案,建議使用 Docker 容器化部署。


七、GitLab 整合策略#

GitLab 提供三種 Merge 策略,與 GitHub 類似但有細微差異:

1. Merge Commit#

保留完整分支歷史,產生合併節點。

2. Squash Commits#

壓縮所有 commit 為單一 commit,適合清理瑣碎歷史。

3. Fast-forward Merge#

GitLab 支援 Fast-forward Merge,這是 GitHub 沒有的選項。適用於分支已基於最新主幹,無需合併節點的情況。

# 在 .gitlab-ci.yml 或專案設定中組態
merge_method: ff

八、DevOps 實踐整合#

混合策略:Jenkins + GitLab#

對於已有 Jenkins 體系的企業:

  1. GitLab 作為程式碼倉庫:管理程式碼與 Code Review
  2. Jenkins 作為主要 CI:執行複雜的建置流程
  3. GitLab CI 作為補充:處理使用者自定義需求

漸進式導入建議#

  1. 階段一:使用 GitLab 管理程式碼與 MR
  2. 階段二:組態簡單的 Lint 與測試 Pipeline
  3. 階段三:整合自動化部署
  4. 階段四:加入安全掃描與監控

即使暫時無法使用 GitLab 全部功能,也建議了解業界的 End-to-End 交付流程,有助於最佳化現有開發流程。


常用組態速查#

.gitlab-ci.yml 關鍵字#

關鍵字說明
stages定義執行階段順序
image指定 Docker 映像
script執行的命令
before_scriptscript 前執行
after_scriptscript 後執行
only僅在指定分支執行
except排除指定分支
when執行條件(manual、on_success)
artifacts產出物(傳遞到下一階段)
cache快取(跨 Pipeline 重用)
environment部署環境
variables環境變數
needsJob 依賴(DAG)

Runner 管理#

操作指令
註冊 Runnergitlab-runner register
啟動 Runnergitlab-runner run
查看狀態gitlab-runner status
停止 Runnergitlab-runner stop
註銷 Runnergitlab-runner unregister