Google App Engineのフレキシブル環境にNuxt.jsをデプロイしてみた

## 概要

Google App Engineのフレキシブル環境にNuxt.jsのSSRアプリをサービスとしてデプロイしてみました。
Nuxt.jsはMacのDockerで開発環境をつくり、```npm```ではなく```yarn```を利用、言語はTypeScriptとSCSSが利用できるようにしました。(趣味

上記を実現するのにすでに良い記事があったのですが、手順としてまとめてみました。
同じ趣味の方は大いにご参考ください^^

### Nuxt.jsとは

Vue.js製フレームワークNuxt.jsではじめるUniversalアプリケーション開発
https://html5experts.jp/potato4d/24346/

>Nuxt.js（ナクストと読みます）はReact.jsベースのSSR用フレームワークであるNext.jsに触発されて作成された、Vue.jsベースのフレームワークです。

です。

## 手順

### Docker環境構築

Dockerはインストール済みの前提です。


環境構築には、下記を大いに参考させてもらいました。感謝！

Dockerでローカル環境を汚さずにNuxt.jsを始めてみる
https://qiita.com/ProjectEuropa/items/d9ee1b8c96084e3bab55

docker-compose.ymlとDockerfileの記述は上記記事をご参考ください。


```sh
> mkdir 任意のディレクトリ
> cd 任意のディレクトリ
> vi docker-compose.yml
> vi Dockerfile
```

docker-composeのバージョンが1の場合、```build``` パラメータ指定方法を変更する必要があります。(1敗

```sh:version1だったー
> docker-compose version

docker-compose version 1.22.0, build f46880f
docker-py version: 3.4.1
CPython version: 3.6.4
OpenSSL version: OpenSSL 1.0.2o  27 Mar 2018
```

参考)
Compose ファイル・リファレンス
http://docs.docker.jp/compose/compose-file.html

>バージョン１のフォーマット では、 build の使い方が異なります

```txt:docker-compose.yml
-   build: 
-     context: ./
+   build: ./
```


で、dockerコンテナを立ち上げてwebコンテナに入ります。

```sh
> docker-compose build
(略)

> docker-compose up -d
(略)

> docker-compose exec web bash

[root@xxxxxxxxxxx html]#
```

### Nuxtアプリの作成と動作確認

無事にコンテナに入れたらnuxtアプリを作成していきます。
今回は、TypeScriptとSCSSを利用します。

下記記事を大いに参考にさせてもらいました。感謝!

Nuxt.js + TypeScript + Sass + ESLint 事始め
https://qiita.com/ryota-yamamoto/items/4b06ef51926df1bdbae8


```sh:コンテナ内
> npm install yarn -g

/usr/bin/yarn -> /usr/lib/node_modules/yarn/bin/yarn.js
/usr/bin/yarnpkg -> /usr/lib/node_modules/yarn/bin/yarn.js
+ yarn@1.9.4
added 1 package in 1.137s

> vue -V

2.9.6

> vue init nuxt-community/typescript-template nuxt-sample

   vue-cli · Generated "nuxt-sample".

   To get started:

     cd nuxt-sample
     npm install # Or yarn
     npm run dev

> cd nuxt-sample/
> yarn
(略)

> yarn add --dev node-sass sass-loader
(略)
```

SCSSにするため、Nuxtアプリ内の記述を変更します。

```vue:components/Card.vue
-<style scoped>
+<style lang="scss" scoped>
```

```vue:pages/index.vue
-<style scoped>
+<style lang="scss" scoped>
```

設定ファイルとmain.cssのファイル名を変更します。

```js:nuxt.config.js
- css: ["~/assets/css/main.css"],
+ css: ["~/assets/css/main.scss"],
```

```sh:コンテナ内
> mv assets/css/main.css assets/css/main.scss
```

準備ができたので、アプリを立ち上げてみます。

```sh:コンテナ内
> yarn run dev

(略)
 OPEN  http://localhost:3000

  nuxt:render Rendering url / +0ms
  nuxt:render Data fetching /: 179ms +0ms
  nuxt:render Rendering url / +13s
  nuxt:render Data fetching /: 33ms +12s
```
はい。
これでホストから下記へアクセスするとページが表示されるはずです。

```sh
open http://localhost:3000/
```
<img width="1020" alt="このヒーローたちは何者なんだ" src="https://qiita-image-store.s3.amazonaws.com/0/48549/313bd02a-ca5b-1d02-7b98-9d485178b608.png">
やったぜ。

### Google App Engineへデプロイ

ここからはGoogle App Engineへデプロイをしてみます。

```gcloud``` コマンドのインストールは下記をご参考ください。
※今回はNode.jsのインストールは不要。

SDK for App Engine のダウンロード
https://cloud.google.com/appengine/docs/flexible/nodejs/download

GCPプロジェクトやデプロイに必要な設定は下記をご参考ください。

GCP プロジェクト、App Engine アプリケーション、課金の管理
https://cloud.google.com/appengine/docs/flexible/nodejs/managing-projects-apps-billing

#### Nuxtアプリのビルド

デプロイするために、Nuxtアプリをビルドします。

```sh:コンテナ内
> yarn run build

yarn run v1.9.4
$ nuxt build
(略)
             Asset    Size  Chunks             Chunk Names
server-bundle.json  189 kB          [emitted]
  nuxt:build Building done +2m
Done in 141.32s.
```

### デプロイ設定

Google App Engineへのデプロイについては下記を参考にさせてもらいました。感謝！

Nuxt.js on Google App Engine（GAE)
https://qiita.com/SatoTakumi/items/4f418dc5c700b9d66d7d


Google App Engineへデプロイするための設定をします。
こちらの作業はコンテナ内・外どちらで行っても問題ありません。

Google App Engineはpackage.jsonの```start```をみてアプリを起動するそうなので、```HOST```と```PORT``` を指定します。

```json:package.json
-   "start": "nuxt start",
+   "start": "HOST=0.0.0.0 PORT=8080 nuxt start",
```

また、Google App Engineのフレキシブル環境でランタイム指定をするのに、package.jsonでnodeのバージョンを指定します。ファイルの最後に追加しましょう。

```json:package.json
- }
+ },
+ "engines": {
+   "node": "9.x"
+ }
```

Google App Engineのデプロイに必要となるapp.yamlを追加します。こちらはNuxtアプリのディレクトリ直下に置きます。

``` sh
touch app.yaml
```

もし、既存のGCPプロジェクトへデプロイする場合には、```service``` を指定します。
**指定しないと```default```サービスへデプロイして痛い目にあいます。(1敗**

```runtime``` の指定は```nodejs```とします。バージョン指定はすでにpackage.jsonで行っていますね。

```yaml:app.yaml
runtime: nodejs
env: flex
# プロジェクトに初めてデプロイする場合は下記設定は不要
service: 任意のサービス名
```

### Google App Engineへデプロイ

準備ができましたので、デプロイします。
こちらはコンテナ外で作業しましょう。

```sh:コンテナ外
> gcloud app deploy

Services to deploy:

descriptor:      [任意のディレクトリ/nuxt-sample/app.yaml]
source:          [任意のディレクトリ/nuxt-sample]
target project:  [GCPのプロジェクトID]
target service:  [サービス名]
target version:  [20180810t135530]
target url:      [https://サービス名-dot-GCPのプロジェクトID.appspot.com]

(略)
Deployed service [サービス名] to [https://サービス名-dot-GCPのプロジェクトID.appspot.com]

You can stream logs from the command line by running:
  $ gcloud app logs tail -s サービス名

To view your application in the web browser run:
  $ gcloud app browse -s サービス名


Updates are available for some Cloud SDK components.  To install them,
please run:
  $ gcloud components update
```
はい。
それでは、上記にあるURLにアクセスしてみましょう。

```sh
https://サービス名-dot-GCPのプロジェクトID.appspot.com
```

<img width="1012" alt="appengine_on_nuxt.png" src="https://qiita-image-store.s3.amazonaws.com/0/48549/901a95f1-6ff5-b3b8-d352-d14c897cd613.png">

やったぜ。
最後に、不要になったらGCP管理コンソールからサービスを削除しておきましょう。

それでは、良きTypeScriptとSCSSでNuxt.jsをDockerコンテナ上で開発、App Engineにデプロイライフを^^(長い


## 参考

Vue.js製フレームワークNuxt.jsではじめるUniversalアプリケーション開発
https://html5experts.jp/potato4d/24346/

Dockerでローカル環境を汚さずにNuxt.jsを始めてみる
https://qiita.com/ProjectEuropa/items/d9ee1b8c96084e3bab55

Compose ファイル・リファレンス
http://docs.docker.jp/compose/compose-file.html

Nuxt.js + TypeScript + Sass + ESLint 事始め
https://qiita.com/ryota-yamamoto/items/4b06ef51926df1bdbae8

Nuxt.js on Google App Engine（GAE)
https://qiita.com/SatoTakumi/items/4f418dc5c700b9d66d7d

Node.js ランタイム
https://cloud.google.com/appengine/docs/flexible/nodejs/runtime

SDK for App Engine のダウンロード
https://cloud.google.com/appengine/docs/flexible/nodejs/download

GCPプロジェクトやデプロイに必要な設定は下記をご参考ください。

GCP プロジェクト、App Engine アプリケーション、課金の管理
https://cloud.google.com/appengine/docs/flexible/nodejs/managing-projects-apps-billing

NPM vs Yarn Cheat Sheet
https://shift.infinite.red/npm-vs-yarn-cheat-sheet-8755b092e5cc

Vue.js+TypeScriptで開発するときの参考記事まとめ
https://qiita.com/kai_kou/items/19b494a41023d84bacc7