Deploy Cloud Run with NestJS and Cloud MongoDB
在 google-github-actions/auth 這篇有提到如何透過 GitHub Actions 向 Google Cloud 進行身份驗證, 這篇則是記錄驗證完後, 如何將 NestJS 應用程式 (並且使用 Cloud MongoDB Atlas 作為資料庫) 部署到 Google Cloud Run 上
google-github-actions/deploy-cloudrun@v2
這邊使用 google-github-actions/deploy-cloudrun 這個 action 來 deploy 到 Google Cloud Run 上, 其中所需要的 Google Auth 設定可參考 google-github-actions/auth 這篇
Update WIP IAM Policy
延續上次的 ci.yml
jobs:
api:
if: ${{ github.event.inputs.api == 'true' }}
permissions:
id-token: write
contents: read
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20.15.0'
- name: Authenticate to Google Cloud
uses: google-github-actions/auth@v2
with:
project_id: ${{ secrets.GCP_PROJECT_ID }}
workload_identity_provider: ${{ secrets.WIF_PROVIDER }}
- name: Set up Cloud SDK
uses: google-github-actions/setup-gcloud@v2
- name: Build and Push to Gcs
run: |
gsutil cp gs://${{ env.BUCKET_FOLDER }}/api/.env.staging apps/api/.env
gcloud auth configure-docker ${{ env.GAR_LOCATION }}-docker.pkg.dev
service=api
tag=${{ github.event.inputs.tag }}
docker build --build-arg TURBO_TOKEN=${{ secrets.TURBO_TOKEN }} --build-arg TURBO_TEAM=${{ secrets.TURBO_TEAM }} -t ${{ env.GAR_LOCATION }}-docker.pkg.dev/${{ secrets.GCP_PROJECT_ID }}/${{ env.REPOSITORY }}/$service:$tag -f ./dockerfiles/$service.Dockerfile . --no-cache
docker push "${{ env.GAR_LOCATION }}-docker.pkg.dev/${{ secrets.GCP_PROJECT_ID }}/${{ env.REPOSITORY }}/$service:$tag"
- name: Deploy to Cloud Run
id: deploy
uses: google-github-actions/deploy-cloudrun@v2
with:
service: api
region: ${{ env.REGION }}
image: ${{ env.GAR_LOCATION }}-docker.pkg.dev/${{ secrets.GCP_PROJECT_ID }}/${{ env.REPOSITORY }}/api:${{ github.event.inputs.tag }}
- name: Show output
run: echo ${{ steps.deploy.outputs.url }}
因為我們將 NestJs 所要用到的 .env
檔案放在 Google Cloud Storage (GCS) 上, 在 action 執行的時候才下載回來而不是直接上傳在 GitHub, 所以我們需要增加可以訪問 GCS 的權限 (storage.objects.get)
另外在 deploy cloud run 的時候則需要能夠建立資源 (iam.serviceAccounts.actAs) 以及訪問 Cloud Run 的權限
權限的精細或更細的限制可自行調整
Troubleshooting
-
當 action 執行 deploy Cloud Run 成功後, 預設的 cloud run 所使用的 port 是 8080, 如果想要更換其他 port 的話, 除了 Dockerfile 有
EXPOSE ${PORT_NUMBER}
之外, 在 cloud run 這邊需要更改為所設定的 port -
當 deploy 上去後, 可能會遇到無法訪問 Cloud Run 在 deploy 後提供的頁面:
The request was not authenticated.
Either allow unauthenticated invocations or set the proper Authorization header.
Read more at https://cloud.google.com/run/docs/securing/authenticating
Additional troubleshooting documentation can be found at: https://cloud.google.com/run/docs/troubleshooting#unauthorized-client即訪問這個服務是需要被授權的, 可以依照自己的需求去參考他所提供的方式, 這邊直接使用 Allowing public 的方式來允許訪問
-
在 deploy 上去的時候可能會遇到 Cloud MongoDB 無法正確連線, 這是因為 Cloud MongoDB Atlas 的 network access 限制, 所以有幾種方式
- cloud mongo 的
Network Access
設定對應的 IP 白名單 - 開啟並設定 Cloud run 的 VPC networking
這邊使用第二種方式, 透過 VPC 來連接 Cloud Run 與 Cloud MongoDB Atlas, Cloud NAT 的部分可以參考之前這篇
建立好之後, 接下來到 Cloud Run 的 Networking Tab, 開啟 VPC
這樣就能解決 MongoDB 連線的問題
- cloud mongo 的