NuxtをCloudRunにデプロイする。

この記事は [Nuxt.js Advent Calendar 2019](https://qiita.com/advent-calendar/2019/nuxt-js) 7日目の記事です。

今回のコード：https://github.com/yujiteshima/cloudrun-test

# NuxtをGoogleCloudRunにデプロイする。
NuxtをCloudRunにデプロイする方法について嵌った部分を中心に説明します。

## 今回やる事
Nuxt.jsの`create-nuxt-app`してだけの状態のアプリををGCPのCloudRunにデプロイしてみるというものです。

## Cloud Runとは
私のざっくりとした理解です。理解がまだまだ不足している分はどんどん色んなサービスを使いながら理解していきたいと思います。

Cloud Runは自分で作ったコンテナを、GCPのサーバ環境上で動かせるサービスです。
誰もアクセスしていない時は課金されず、誰かがアクセスしてきた時に立ち上がり、立ち上がっている時間だけが課金対象となるサービスです。

多くのアクセスがこれば自動でスケールアップして、少なくなれば自動でスケールダウンしてくれるというスケーリングも面倒をみてくれます。

CloudFunctionとの一番の違いはコンテナ上で動かすので、ランタイムが制限されていない事のように思います。
GKEとの違いは、kubernetesのアップデートの管理をCloudRunでは追わなく
良いということ。GKEの方が面倒をみなくてならない事が多い分自由度が高いという感じがします。

このFunctionsとGKEの間の性格を持っている為、コンテナで動かしたいけどGKEを使うほどではない、もっと簡単に面倒をみる事が少ないように使いたいという時にCloudRunの存在価値があるのかなと思いました。

## Cloud Runを使う準備

GCPのサインアップをされてない方はサインアップして下さい。
請求先（クレジットカードの情報）が必要です。
初めて利用される方は$300の無料クレジットがつくはずです。

### Cloud SDK

- Cloud SDKをインストールしていない方はインストールして下さい。
https://cloud.google.com/sdk/install?hl=JA



CloudSDKをアップデートしておきます。
Beta版コンポーネントのインストールもしておきます。

```
$ gcloud components update
$ gcloud components install beta
```

### GCPのコンソールでプロジェクトを作リます。
作成はプロジェクトの作成から作成します。

<img width="813" alt="スクリーンショット 2019-12-11 12.45.12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252625/cbd43cb3-c784-6186-e623-31e4d0447fcf.png">

好きな名前をつけて下さい。よくある重複している名前は勝手に番号を末尾につけてくれます、このプロジェクトの名前は後で何回か使います。

<img width="673" alt="スクリーンショット 2019-12-11 12.45.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252625/91306088-9c11-13d5-a8cb-6c16bb504335.png">


プロジェクトの請求を有効にしておく必要があります。

メニューのお支払いから設定して下さい。

<img width="602" alt="スクリーンショット 2019-12-11 12.47.11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252625/1eeda39f-7a11-bb01-5b64-a63d797f33d6.png">

<img width="673" alt="スクリーンショット 2019-12-11 12.47.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252625/8bd6da37-ddd2-2b3c-3f56-3f5e51adbde6.png">

### CloudBuildを有効化しておく

クラウドビルドを使うので有効化しておきます。

<img width="297" alt="スクリーンショット 2019-12-11 13.24.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252625/e36c7a75-1ae3-e455-bedb-745c53fbbd0f.png">

### CloudRunを有効化しておく

<img width="297" alt="スクリーンショット 2019-12-11 13.27.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252625/f3f14e95-3fb7-615b-36b2-ad6babaa08d4.png">




## Nuxtのプロジェクト作成

はじめからExpress入れて作成します。
Functions等でExpressのミドルウエアとしてNuxtを動かして、SSRのデプロイをした事がある方は馴染みある形だと思いますが、Chose custom server frameworkでExpress選んでおけば、よしなにやってくれます。

```bash
$ npx create-nuxt-app sample-app
```

```bash
create-nuxt-app v2.11.1
✨  Generating Nuxt.js project in sample-app
? Project name sample-app
? Project description My exquisite Nuxt.js project
? Author name Yuji Teshima
? Choose the package manager Yarn
? Choose UI framework Bulma
? Choose custom server framework Express
? Choose Nuxt.js modules Axios, Progressive Web App (PWA) Support
? Choose linting tools ESLint, Prettier, Lint staged files
? Choose test framework Jest
? Choose rendering mode Universal (SSR)
? Choose development tools (Press <space> to select, <a> to toggle all, <i> to invert selection)
yarn run v1.19.0
```

## portの変更

動作確認をしてみます。

```bash
$ yarn run dev
```

するとターミナルにリッスンしているアプリケーションポートが表示されます。

```bash
$ READY  Server listening on http://localhost:3000
```

クラウドの実行には、`process.env.PORT`を設定しておく必要があります。
また`localhost`や`127.0.0.1`では無くて`0.0.0.0`をホストにしておかなくてはならないので、その設定を書き加えていきます。

nuxt.config.jsにserverの設定を書き加えます。

```js:nuxt.config.js
server: {
    port: process.env.PORT || 3000,
    host: '0.0.0.0',
    timing: false
  }
```

## Dockerfileを作成する

```Dockerfile
From node:latest

WORKDIR /src

COPY . .
Run yarn install \
    --prefer-offline \
    --frozen-lockfile\
    --non-interractive \
    --production=false

Run yarn build

CMD [ "yarn", "start" ]
```

## クラウドビルドの設定をyamlで書く

```yaml:cloud-build.yml
steps:
  - name: gcr.io/cloud-builders/docker
    args:
      [
        "build",
        "-f",
        "Dockerfile",
        "-t",
        "gcr.io/gcpコンソールで先程作ったプロジェクトName/コンテナの名前（好きな名前）",
        ".",
      ]
images:
  - gcr.io/gcpコンソールで先程作ったプロジェクトName/コンテナの名前（好きな名前）
```

## Google Cloud Buildでビルドする

```bash
gcloud builds submit --project "gcpコンソールで先程作ったプロジェクトName" --config=./cloud-build.yaml
```

## デプロイする
```bash
gcloud beta run deploy cloud-run-name --region us-central1 --project "gcpコンソールで先程作ったプロジェクトName" --image gcr.io/gcpコンソールで先程作ったプロジェクトName/コンテナの名前（好きな名前）
```

リージョンはBeta版の時はus-central1に制限されていましたが、2019 年 11 月 14 日にGAになった際に、`asia-northeast1(東京)`も追加されました。

デプロイ時にオプションで渡していた値は事前に登録しておく事も出来ます。

```bash:例
$ gcloud config set project "gcpコンソールで先程作ったプロジェクトName"
$ gcloud config set run/region asia-northeast1
```

成功すると、ページのアドレスがターミナルに表示されます。

```bash
Service [sample-app] revision [sample-app-00001-puw] has been deployed and is serving 100 percent of traffic at https://sample-app-<生成された値>-uc.a.run.app
```
現時点で表示されたアドレスにリクエストしても、エラーが表示されます。

## 公開設定の変更

このままだとデプロイしたものを誰でも見れるようにはなっていません。
見れるようにするには、公開設定を変えなくてはなりません。
自身が利用するAPIであればそれに応じた公開設定をする必要があります。
今回は誰でも見れるようにAllUserに変更してデプロイ出来ているか確認しておきます。

コンソールでCloudRunのページから権限を変更します。
<img width="664" alt="スクリーンショット 2019-12-11 13.30.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252625/3baf997e-b221-98f4-3f4e-3b0783c86c97.png">

<img width="667" alt="スクリーンショット 2019-12-11 12.04.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252625/fe3a85e6-4dbf-ff9b-e6fd-72a49c4cf627.png">

これで、表示されるはずです。

<img width="720" alt="スクリーンショット 2019-12-11 13.35.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252625/096e652f-1e54-4886-4dd8-656bee657b8f.png">

今回は初期画面が表示されるだけですが、きちんと表示できれば成功です。

## まとめ

Docker使い初めの、私のような初級者には、自分が作ったコンテナが実際GCPのサーバ上で動いているというだけで、少し感動しました。
どんどん使っていきたいです。あらためて、使ってみて初めて理解できるという事あると思いました。