iT邦幫忙

2026 iThome 鐵人賽

DAY 27
0

前言

在 Day 12 時,我們手動輸入 gcloud run deploy 將 KAKERU 後端 API 推上雲端。隨著開發進入尾聲,頻繁的手動部署既費時又容易出錯。今天我們導入 GitHub Actions 建立 CI/CD Pipeline:未來只要將程式碼 Push 到 GitHub 的 main 分支,雲端虛擬機就會自動接手編譯、打包 Docker Image,並以「零停機 (Zero-Downtime)」的方式平滑發佈到 GCP Cloud Run。

動手實作 1:建立 GitHub Private 專案與推送程式碼

  1. 在 GitHub 建立私有專案(例如:kakeru-ai-backend),設為Private
  2. 在本地專案執行以下指令綁定並推送:
git init
git add .
git commit -m "init: 首次提交 KAKERU 後端程式碼"
git branch -M main
git remote add origin https://github.com/[你的帳號]/專案名稱.git
git push -u origin main

動手實作 2:配置 GCP 權限與 GitHub Secrets

要讓 GitHub Actions 能操作 GCP,需建立具備適當權限的服務帳戶與金鑰。

1. 啟用必要 GCP API

在 GCP 的裡,所有服務預設都是關閉的,這是為了防止帳號被盜用時產生無預期的鉅額帳單。這個指令是告訴 Google:「我要在目前這個專案裡,解鎖這三項特定的雲端武器」。

  • cloudbuild.googleapis.com雲端編譯器。我們不需要在本地端跑 Docker,而是把程式碼丟給 Cloud Build,讓它在雲端幫我們把 Java 程式碼打包成 Docker Image。
  • artifactregistry.googleapis.com私有映像檔倉庫。打包好的 Docker Image 總要有地方放,這就是專屬我們專案的無菌倉庫。
  • run.googleapis.com無伺服器執行環境。最後我們要將倉庫裡的 Image 部署到 Cloud Run 上並對外開放網路。
gcloud services enable \
  cloudbuild.googleapis.com \
  run.googleapis.com \
  artifactregistry.googleapis.com

2. 建立服務帳戶並賦予權限,一位專屬部署的機器人

我們要避免把擁有最高權限的「個人 Google 帳號密碼」交給 GitHub。好的做法是透過 IAM 建立一個「Service Account (服務帳戶)」,你可以把它想像成一位只負責部署的「虛擬員工」,並嚴格限制它只能做以下 5 件事:

建立服務帳戶(如 github-actions-deploy),並賦予以下 5 個關鍵角色:

  • Cloud Run 管理員:允許機器人更新 Cloud Run 的設定,並在部署完成後,將流量無縫切換到最新版本。
  • 服務帳戶使用者:這是一個資安代理權限。允許這個部署機器人在啟動 Cloud Run 時,能夠「扮演」Cloud Run 執行時期的身分。
  • Storage 管理員:當 GitHub 把程式碼送到 GCP 時,Cloud Build 會需要一個暫存的 Cloud Storage (GCS) 空間來放原始碼,這個權限讓它能自由讀寫暫存檔。
  • Cloud Build 編輯者:允許機器人正式向 GCP 提交「幫我打包 Docker」的工作指令。
  • 檢視者:這個權限看似不起眼卻非常重要。有了它,GitHub Actions 才能即時讀取 GCP 端的編譯日誌,讓你可以在 GitHub 後台看著綠色勾勾與進度條一條條跑完。

3. 設定 GitHub Secrets:將晶片鑰匙安全地交給 GitHub

既然這位「部署機器人」已經在 GCP 註冊好了,我們必須把它的身分證(JSON 金鑰)交給 GitHub,GitHub Actions 才有辦法在雲端登入 GCP。

  • 為什麼要用 Secrets? 我們不能把包含密碼的 JSON 檔 commit 到 Git 紀錄裡,跟Gemini API 的 Key 一樣會有洩漏的風險。
  • GCP_CREDENTIALS 的作用:將 JSON 金鑰貼進 GitHub Secrets 後,它會被加密。當 GitHub Actions Pipeline 啟動時,它會在背景默默解密這把鑰匙來登入 GCP。最棒的是,如果我們不小心在腳本中寫了會把這把鑰匙印出來的指令,GitHub 會在終端機日誌裡自動將它打碼成 **,徹底避免金鑰外洩的風險。

動手實作 3:撰寫 GitHub Actions 部署腳本

在專案根目錄建立 .github/workflows/deploy.yml

name: Deploy to Cloud Run

on:
  push:
    branches: [ "main" ]

env:
  PROJECT_ID: kakeru-ai
  REGION: asia-east1
  SERVICE_NAME: kakeru-ai-api

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest

    steps:
      # 1. 取得最新程式碼
      - name: Checkout code
        uses: actions/checkout@v4

      # 2. 準備 Java 21 環境
      - name: Set up JDK 21
        uses: actions/setup-java@v4
        with:
          java-version: '21'
          distribution: 'temurin'

      # 3. 執行 Maven 編譯檢查
      - name: Build with Maven
        run: mvn clean package -DskipTests

      # 4. 透過 Secret 驗證 GCP 身分
      - name: Google Auth
        uses: google-github-actions/auth@v2
        with:
          credentials_json: '${{ secrets.GCP_CREDENTIALS }}'

      # 5. 透過 Cloud Build 打包並推播 Docker Image
      - name: Build and Push Docker Image
        run: |
          gcloud builds submit --tag gcr.io/$PROJECT_ID/$SERVICE_NAME

      # 6. 部署至 Cloud Run (零停機發佈)
      - name: Deploy to Cloud Run
        run: |
          gcloud run deploy $SERVICE_NAME \
            --image gcr.io/$PROJECT_ID/$SERVICE_NAME \
            --region $REGION \
            --allow-unauthenticated

動手實作 4:觸發自動化流水線

將工作流程腳本推送到遠端:

git add.
git commit -m "ci: 建立 GitHub Actions 自動部署腳本"
git push origin main

前往 GitHub 倉庫的 Actions 頁籤,即可看到部署流程自動運行。等待 2~3 分鐘所有步驟亮起綠色打勾(✅),即代表部署完成!
Github Pipeline:
https://ithelp.ithome.com.tw/upload/images/20260905/20165043UmWH7DjGs1.png

GitHub Actions:
https://ithelp.ithome.com.tw/upload/images/20260905/20165043Tbid7d9c1B.png

部署到 Cloud Run:
https://ithelp.ithome.com.tw/upload/images/20260905/20165043f0eOU42DgT.png

踩坑與避雷指南

  1. JDK 版本一致:Actions 的 setup-java 版本需與 pom.xml 的 Java 版本(Java 21)一致,避免編譯失敗。
  2. Cloud Build API 需事先啟用:若未啟用 cloudbuild.googleapis.com,執行 gcloud builds submit 時會被拒絕。
  3. 服務帳戶權限要給齊:除了基本的 Cloud Run 與 Storage 權限外,務必包含 Cloud Build 編輯者 與 檢視者 (Viewer),否則 CLI 在串流建置日誌時會因權限不足中斷。

今日總結與明日預告

今天我們透過 GitHub Actions 與 GCP Cloud Build / Cloud Run,完成了後端 API 的自動化 CI/CD Pipeline。

實務思維:多分支與多環境治理→在今天的實作中,為了專注於自動化核心觀念,我們直接以 main 分支對應單一 Cloud Run 服務。但在實際團隊專案中,通常會搭配更嚴謹的分支與環境策略:
dev 分支:自動部署至內部開發環境 (dev),供工程師快速驗證。
alpha / staging /sit 分支:自動部署至測試環境,供 QA、前端 APP 整合與內部驗收。
main / prod 分支:對應正式上線環境,並通常會搭配 GitHub 的 Environment Protection 機制,由主管或負責人 Approve 後才發佈。
再根據上面的這些分支,推送到各個環境,git push直接部署的情況相對較少,因為爆炸的話後果不堪設想😆。

明天(Day 28)將進行前端 CI/CD 實戰,導入 Expo 的 EAS (Expo Application Services) 與 OTA 熱更新 技術,敬請期待!


上一篇
Day 26 | 自動部署前的細節打磨:實作深淺色模式與 API 載入鎖定防呆
下一篇
Day 28 | 前端 CI/CD:打破本機限制!Expo EAS 雲端打包與 OTA 更新
系列文
單鐵的人生如履薄冰!AI 教練 APP 30天開發旅程,你說能走到最後嗎?30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言