1
2024-05-10
#GCP

用 Github Actions 在 Google Cloud Run 上部署 Next.js

#前言

Cloud Run 是什麼?

是Google Cloud 的 Serverless(無伺服器)服務之一。

傳統的應用部署通常需要配置和管理伺服器,包括操作系統更新、硬體維護、資源分配等。而無伺服器架構讓我們可以將應用程序部署到雲端,不必關心底層的伺服器硬體或運行環境,這些操作都由 Google Cloud 來處理。

必須將程式包裝成 Container image ,才能夠部署至 Cloud Run。

Docker 是什麼?

為了將程式包裝成 Container image,我們會使用 Docker。 Docker 是個輕量級的虛擬化技術,可以把你的應用程式連同環境一起打包,部署的時候就不用再擔心環境的問題。

#- step1. 把我們的 Next.js 應用程式 Docker 化

1. 在我們的 Next.js 專案裡創建一個 Dockerfile

簡單的內容配置如下

#指定使用 Node.js 18.17.0 版本
FROM node:18.17.0

#設定工作目錄為 /app,表示之後的命令將在這個目錄下執行
WORKDIR /app

#安裝相依套件
COPY package.json yarn.lock ./
RUN yarn install && yarn cache clean

#將本地目錄下的所有檔案複製到容器的 /app 目錄中
COPY . .

#在容器中執行 yarn build 命令
RUN yarn build

#使用 3000 port
EXPOSE 3000

#設定容器啟動時執行的預設命令為 yarn start
CMD [ "yarn", "start" ]

Imgur

2. 再來我們要確認是否 container 可以在本地正常運行

使用以下指令來創建一個映像 (image)

docker build -f Dockerfile -t <專案名稱> .

使用以下指令來運行一個基於剛剛創建的映像的容器 (container)

docker run -i -p 3000:3000 <專案名稱>

然後到 http://localhost:3000/ 看看程式是否正常運行

#- step2. 配置 Google Cloud

1. 創建一個專案

到這個連結 https://console.cloud.google.com/projectcreate
輸入專案名稱,這邊使用 cloud-run-demo

Imgur

2. 創建一個服務帳戶

這是要用在 Github Actions
IAM 管理 > 服務帳戶 > 建立服務帳戶

Imgur

Imgur

3.依序填入三個步驟

Imgur

4.再來要創建一個金鑰

這個金鑰是用於跑 Github Actions 時認證身分的
點擊管理金鑰 Imgur

點擊建立新的金鑰,會跳出一個彈窗,選擇 JSON,會下載一個金鑰的 JSONImgur

#- step3. 更新 package.jsonScripts

執行 start 時,需要從 cloud run 接收一個 PORT

"scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start -p $PORT" // <-- update here
},

補充:改成這樣後想在本地端執行的話,可用以下指令

PORT=3000 npm start

#- step4. 配置 Github Actions

1. 創建 cloud-run.yml

.github > workflows > cloud-run.yml

Imgur

cloud-run.yml 內容如下

name: nextjs-cloud-run

# 工作流程將在將代碼推送到 master 或 main 分支時觸發。
on:
  push:
    branches:
      - master
      - main

# 定義環境變數,用於設定 Cloud Run 相關的項目
env:
  CLOUD_RUN_PROJECT_ID: ${{ secrets.CLOUD_RUN_PROJECT_NAME }}
  CLOUD_RUN_REGION: asia-northeast1
  # 自行填入專案名稱
  REPO_NAME: cloud-run-demo

# 定義了一個名為 build-and-deploy 的工作,這個工作將運行在 ubuntu-latest 環境上。
jobs:
  build-and-deploy:
    name: Setup, Build, and Deploy
    runs-on: ubuntu-latest
    steps:

    # 步驟:從 GitHub 倉庫中檢出代碼。
    - name: Checkout
      uses: actions/checkout@v2

    # 步驟:使用 Google Cloud Actions 設置 gcloud 並驗證服務帳戶。
    - uses: google-github-actions/setup-gcloud@v0.2.0
      with:
        project_id: ${{ secrets.CLOUD_RUN_PROJECT_NAME }}
        service_account_key: ${{ secrets.CLOUD_RUN_SERVICE_ACCOUNT }}
        service_account_email: ${{ secrets.CLOUD_RUN_SERVICE_ACCOUNT_EMAIL }}

    # 步驟:啟用 Container Registry 和 Cloud Run API,並設置 Docker 認證。
    - name: Enable the necessary APIs and enable docker auth
      run: |-
        gcloud services enable containerregistry.googleapis.com
        gcloud services enable run.googleapis.com
        gcloud --quiet auth configure-docker

    # 構建映像,並為鏡像添加標籤。
    - name: Build and tag image
      run: |-
        docker build . --tag "gcr.io/$CLOUD_RUN_PROJECT_ID/$REPO_NAME:$GITHUB_SHA"

    # 將映像推送到 Google Container Registry。
    - name: Push image to GCR
      run: |-
        docker push gcr.io/$CLOUD_RUN_PROJECT_ID/$REPO_NAME:$GITHUB_SHA

    # 部署
    - name: Deploy
      run: |-
        gcloud components install beta --quiet
        gcloud beta run deploy $REPO_NAME --image gcr.io/$CLOUD_RUN_PROJECT_ID/$REPO_NAME:$GITHUB_SHA \
          --project $CLOUD_RUN_PROJECT_ID \
          --platform managed \
          --region $CLOUD_RUN_REGION \
          --allow-unauthenticated \
          --quiet

2. 設定 secrets

cloud-run.yml 中可以看到有些 secrets,例如 ${{ secrets.CLOUD_RUN_PROJECT_NAME }} ,我們要在 Github 的 Action Secrets 來做設定。 Imgur

Secrets:

  • CLOUD_RUN_PROJECT_NAME: 專案的 ID
  • CLOUD_RUN_SERVICE_ACCOUNT — 這是 base64 編碼的私鑰。我們要把剛剛下載的 JSON 檔轉為 base64 編碼並貼上。
    macOS,可以直接這樣:base64 <存放JSON檔的路徑>
  • CLOUD_RUN_SERVICE_ACCOUNT_EMAIL:服務帳戶的 EMAIL Imgur

#- step5. Push code 至 Github 就完成了 🎉


參考資料:

main*
© 2024 All Rights Reserved. IRIS Studio