くらげになりたい。

くらげのようにふわふわ生きたい日曜プログラマなブログ。趣味の備忘録です。

monorepoでもGitHub Actions+OIDCでNuxtをCloud Runにデプロイしたい

前回の続き(*´ω`*)
pnpm x Turborepoでつくったmonorepo構成で、
ソースからデプロイしようと思ったら、ハマったときにの備忘録(*´ω`*)

ディレクトリ構成

構成としてはこんな感じ。

- packages/
  - common-lib/
    - package.json
  - nuxt-app
    - .output
    - app.vue
    - nuxt.config.ts
    - package.json
    - package.run.json
- package.json
- pnpm-workspace.yaml
- turbo.json

Nuxtはv3.5.3のSSR

workflowファイル

最終的なworkflowファイルはこんな感じ。
基本的な部分は以前の記事を参考に。

name: "Deploy to Cloud Run"
"on":
  push:
    branches:
      - main
  workflow_dispatch:

env:
  SERVICE_ACCOUNT: "YOUR_SERVICE_ACCOUNT_EMAIL"
  PROVIDER: "YOUR_WORKLOAD_IDENTITY_PROVIDER"
  SERVICE_NAME: "YOUR_CLOUD_RUN_SERVICE_NAME"
  SERVICE_REGION: "asia-northeast1"

jobs:
  build_and_deploy_dev:
    runs-on: ubuntu-latest
    # Add "id-token" with the intended permissions.
    permissions:
      id-token: write
      contents: read
    steps:
      # checkout
      - uses: actions/checkout@v3
      
      # setup pnpm
      - uses: pnpm/action-setup@v2.2.4
        with:
          version: 8
      - uses: actions/setup-node@v3
        with:
          node-version: "18"
          cache: "pnpm"
          
      # setup gcloud CLI with OIDC
      - uses: google-github-actions/auth@v1
        with:
          service_account: ${{ env.SERVICE_ACCOUNT }}
          workload_identity_provider: ${{ env.PROVIDER }}
      
      # install and build
      - run: pnpm install && pnpm build
      
      # prepare for deploy
      - name: copy package.json
        run: cp ./packages/nuxt-app/package.run.json ./packages/nuxt-app/.output/package.json
        
      # deploy to cloud run
      - run: gcloud run deploy ${SERVICE_NAME} --source ./packages/nuxt-app/.output --region ${SERVICE_REGION} --allow-unauthenticated

./packages/nuxt-app/package.run.jsonの中身はこんな感じ。

{
  "engines": {
    "pnpm": ">=8",
    "node": ">=18"
  },
  "scripts": {
    "start": "node ./server/index.mjs"
  }
}

ハマったポイント

全パッケージがデプロイされてしまう

過去の記事のまま、

$ gcloud run deploy ${SERVICE_NAME} --source .

で試してみたら、全パッケージがCloud Runにのる対象に。。

対象パッケージ(nuxt-app)のビルド結果だけをのせたい。。

Cloud Build上でもpnpm buildが実行される

次に試したのがこれ。

$ gcloud run deploy ${SERVICE_NAME} --source ./packages/nuxt-app

ドキュメントにもある通り、package.jsonscript.buildがあると、
pnpm buildが実行される。

ただ、GitHub Actions上でビルド済みのため、
ビルド結果だけをのせたい。。

サーバが起動しない

次に試したのがこれ。

$ gcloud run deploy ${SERVICE_NAME} --source ./packages/nuxt-app/.output

試してみるけれど、うまくサーバが実行されない。。

それもそのはずで、.output/にはpackage.jsonがない。

$ tree .output/ --dirsfirst -L 1
.output/
├── public
├── server
└── nitro.json

Buildpackでは、pnpm startが実行されるため、
scripts.startを含むpackage.jsonが必要。

解決策

なので、冒頭にあるようなpackage.run.jsonを用意し、
.output/package.jsonとしてコピーすることで対応した。

{
  "engines": {
    "pnpm": ">=8",
    "node": ">=18"
  },
  "scripts": {
    "start": "node ./server/index.mjs"
  }
}

以上!! これでmonorepoでも個別のパッケージがデプロイできるように(*´ω`*)

参考にしたサイトさま