Nuxt.jsプロジェクトをCircleCIでGCPへデプロイする

【GCP】プロジェクトの作成

https://console.cloud.google.com/ へとアクセスし、プロジェクトを新規作成します。
gcpプロジェクト作成
「作成」を押下し、少し待つとプロジェクトが作成されます。
GCPプロジェクト作成後

【GCP】App Engine アプリケーションの有効化

App Engine のアプリケーションの有効化を行います。今回はGUIで実施します。
左上のハンバーガーメニュー(ナビゲーションメニュー) > 「App Engine」 を押下します。
AppEngine
アプリケーションの追加を押下すると、リージョンの選択画面へ遷移するので任意のリージョンを選択します。
AppEngineリージョン選択
次に言語の選択画面に遷移するので、「Node.js」を選択します。
AppEngine言語選択
AppEngineが正常に作成されれば完了です。
AppEngine作成完了

【GCP】APIを有効化

CircleCIからデプロイするための API を有効化します。
左上のハンバーガーメニュー(ナビゲーションメニュー) > 「APIとサービス」 を押下します。
APIとサービス

上部の「APIとサービスを有効化」を押下します。
検索ボックスが表示されるので、「App Engine」と検索します。

選択肢に「App Engine Admin API」があると思いますのでそれを有効化します。
AppEngineAdminAPI

また、ビルドに必要な「Cloud Build」も有効化します。
CloudBuildAPI

【GCP】サービスアカウントの作成

デプロイする CircleCI 用ユーザーを作成します。
左上のハンバーガーメニュー(ナビゲーションメニュー) >「IAMと管理」を押下、画面遷移し、左メニューの「サービスアカウント」を押下します。
サービスとアカウントの追加

画面上部の「サービスアカウントの追加」を押下し、サービスアカウントを追加します。

任意のアカウント名で作成します。
サービスアカウント名

作成するとそのアカウントの権限設定画面に遷移します。
以下の4つの権限を設定します。
・App Engine管理者
・環境とストレージオブジェクトの管理者
・Cloud Build サービスアカウント
・Cloud Build 編集者

サービスアカウント権限

ロールを作成すると「アクセス権の付与」、「キーの作成」が表示されます。
アクセス権は今回不要なので「キーの作成」をJSON形式で作成します。
キーの作成json

jsonがダウンロードできたら保管し、完了を押下します。
ここまででGCPの設定は完了です。

Nuxtプロジェクトの作成

create-nuxt-app お好きにNuxtプロジェクトを作成します。

[MacbookAirtakumi ~/project/git$ npx create-nuxt-app sample-nuxt-ci                    

create-nuxt-app v2.15.0
✨  Generating Nuxt.js project in sample-nuxt-ci
? Project name sample-nuxt-ci
? Project description My wondrous Nuxt.js project
? Author name takumi
? Choose programming language JavaScript
? Choose the package manager Npm
? Choose UI framework None
? Choose custom server framework Express
? Choose Nuxt.js modules Axios
? Choose linting tools ESLint
? Choose test framework Jest
? Choose rendering mode Single Page App
? Choose development tools jsconfig.json (Recommended for VS Code)

念の為、npm run dev コマンドで起動し、localhost:3000へアクセスし確認
localhost:3000

App Engineの設定ファイルの追加

App Engine で動作させるためのapp.yaml というファイルを作成します。
今回は以下のように設定しました。
app.yamlのドキュメントはこちら

runtime: nodejs12
instance_class: F2
handlers:
  - url: /_nuxt
    static_dir: .nuxt/dist/client
    secure: always
  - url: /(.*\.(gif|png|jpg|ico|txt))$
    static_files: static/\1
    upload: static/.*\.(gif|png|jpg|ico|txt)$
    secure: always
  - url: /.*
    script: auto
    secure: always
env_variables:
  HOST: '127.0.0.1'
  NODE_ENV: 'production'

Circle CI の設定ファイルの追加

今回は以下のように設定ファイルを追加します。
circleciのconfig.ymlのドキュメントはこちら

[MacbookAirtakumi ~/project/git/sample-nuxt-ci$ cat .circleci/config.yml 
version: 2
jobs:
  build:
    working_directory: ~/app
    docker:
      - image: circleci/node:12
    steps:
      - checkout
      - run: echo 1 # TODO:TEST
  deploy:
    working_directory: ~/app
    docker:
      - image: google/cloud-sdk:217.0.0-alpine
    steps:
      - checkout
      - run: apk add --no-cache nodejs npm yarn
      - run: npm install
      - run: npm run build
      - run: echo $GCLOUD_SERVICE_KEY > ${HOME}/gcloud-service-key.json
      - run: gcloud auth activate-service-account --key-file=${HOME}/gcloud-service-key.json
      - run: gcloud app deploy --quiet --project $GCP_PROJECT_ID

workflows:
  version: 2
  main:
    jobs:
#      - build # TODO:TEST
      - deploy:
          filters:
            branches:
              only: master

ここまでできたらgitにpushしておきます。
コードの成果物はこのような形です。

[MacbookAirtakumi ~/project/git/sample-nuxt-ci$ tree -L 2 -I node_modules
.
├── README.md
├── app.yaml
├── assets
│   └── README.md
├── components
│   ├── Logo.vue
│   └── README.md
├── jest.config.js
├── jsconfig.json
├── layouts
│   ├── README.md
│   └── default.vue
├── middleware
│   └── README.md
├── nuxt.config.js
├── package-lock.json
├── package.json
├── pages
│   ├── README.md
│   └── index.vue
├── plugins
│   └── README.md
├── server
│   └── index.js
├── static
│   ├── README.md
│   └── favicon.ico
├── store
│   └── README.md
└── test
    └── Logo.spec.js

CircleCI上の設定

先程ダウンロードした App Engine のサービスアカウントのjsonをCircleCIに設定します。
ターミナルで対象をpbcopyします。

cat sample-276209-97c0bfb1c7ed.json| pbcopy

以下のURLにアクセスし、画像のように
Name: GCLOUD_SERVICE_KEY
Value: {pbcopyしたjson}
で設定します。
https://circleci.com/gh/{ORG名}/{Repository名}:repo-name/edit#env-vars
circleciの設定

また、
Name: GCP_PROJECT_ID
Value: {GCPのプロジェクトID}
で設定します。
プロジェクト情報

ビルド実行

上記CircleCI上で設定した画面で「Follow Project」を押下しビルド画面に遷移します。
ビルド画面
すでにビルドが走っていると失敗するため、
リトライします。

デプロイ確認

CircleCIが正常終了したのを確認できたら、http://{project-ID}.appspot.com にアクセスしてみます。


以上で、GCPにNuxt.jsのプロジェクトをデプロイすることができました。

最後に

このあとはドメインを購入し、Cloud DNSでホスティングすれば外部公開できるはずです。