Nuxt.jsのSSRモードとGoogle App Engine(GAE)をつかうとウェブアプリがお手軽につくれそうだったので試してみました。
Nuxt.jsのインストール
公式ドキュメントの create-nuxt-app
でセットアップ
- 今回はGAEでサーバサイドレンダリングしたいので、セットアップ時にSSRモードを選択
- インストールには、Yarn を使いました
Nuxt.jsにデプロイ用設定
- Nuxt.jsのルートディレクトリにGAEの設定ファイルをつくります
- ドキュメントを参考にしました。( https://ja.nuxtjs.org/docs/2.x/deployment/appengine-deployment/ )
runtime: nodejs14
instance_class: F1
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: '0.0.0.0'
基本は公式のサンプルのままですが少し変更しました
- runtimeですが、公式ではnodejs10を指定していましたが、この記事を書いている時点でGAEにnodejs14がリリースされていたので、バージョンを変更して14を指定しました。
- instance_class、今回は練習なので最小構成のF1です。
Google App Engine の作成
公式ドキュメント
1.上記ドキュメントの[始める前に]の項目にある準備が終わったら
2.Nuxt.jsのルートドキュメントで初期化コマンド
$ gcloud app create --project=[YOUR_PROJECT_ID]
3.ビルドしてデプロイするためのファイルを書き出す
$ yarn build
4.デプロイ
$ gcloud app deploy
5.(以下のコマンドで開けます)
$ gcloud app browse
以上でデプロイ完了
すでにGAE上でNuxt.jsが起動して、ブラウザから閲覧できるようになっているはずです。
フルマネージド型のサーバーレスプラットフォームとはよく言ったもので、サーバ周りをまるっと担ってくれます。
とても手軽で便利です。
Cloud Buildを使ってgithubリポジトリから自動的にデプロイ
さらにCloud Buildを使うと、githubにpushしたタイミングなどで自動的にデプロイできます。
トリガーは色々設定できますが、自分は決められた名前のtagをpushしたタイミングで発火するようにしました。
公式ドキュメント
デプロイ前に自動処理
自動デプロイの設定が終わったら、デプロイ時に一緒に実行してほしい処理を設定していきます。
cloudbuild.yaml というファイルで指示しておくと、デプロイ時に自動実行してくれます。
今回は
- ビルド(Nuxt.jsからデプロイ用ファイルを書き出す)
- 環境変数の設定(リポジトリに保存したくない情報などをGAEに設定する)
の2点を実行するように設定しました。
ビルド
ビルドコマンドでデプロイ用の静的JSファイルなどを作成します。
環境変数の設定
GAEで使う環境変数は app.yaml
の env_variables
に書いておくとGAE環境に設定することができます。
しかし、自動デプロイのためには app.yaml をリポジトリにアップロードしないといけないので、DB接続情報などオープンにしたくない情報を保存するのに不安が残ります。
そこで、CloudBuildに変数を設定しておき、デプロイ前にapp.yamlに書き出すようにします。
今回つくったcloudbuild.yamlです。これをプロジェクトのルートに設置します。
steps:
- name: 'gcr.io/cloud-builders/gcloud'
entrypoint: /bin/sh
args:
- '-c'
- |
cat << EOF > secret.yaml
env_variables:
DB_USER: $_DB_USER
DB_PASSWORD: $_DB_PASSWORD
DB_NAME: $_DB_NAME
EOF
- name: node
entrypoint: yarn
args:
- 'install'
- name: node
entrypoint: yarn
args:
- 'build'
- name: gcr.io/google.com/cloudsdktool/cloud-sdk
id: Deploy
entrypoint: gcloud
args:
- app
- deploy
- '--appyaml=${_APP_YAML}'
- '--project=${PROJECT_ID}'
- '--version=${_VERSION}'
- '--quiet'
options:
substitutionOption: ALLOW_LOOSE
substitutions:
_APP_YAML: 'app.yaml'
_VERSION: '${COMMIT_SHA}'
CloudBuidに設定した変数に合わせて env_variables:
のところを書き換えます。
env_variables:
GAEの環境変数名: $_CloudBuild変数名
GAEの環境変数名: $_CloudBuild変数名
みたいな書き方でGAEに送り込みたい環境変数の分だけ設定します。
それを、secret.yaml
に書き出して、app.yaml
にincludeするという仕組みです。(下でやります)
これで
- CloudBuildの変数を環境設定ファイルに書き出し
- Nuxtをビルド
- デプロイ
が実行されます。
app.yaml修正
app.yamlの末尾に追加します。
cloudbuild.yamlで生成した環境変数をGAE設定ファイルにインクルードします。
これで、GAEデプロイ時に環境変数が設定されます。
...
includes:
- secret.yaml
CloudBuild 参考サイト
Cloudbuildの設定で下記のサイトがとても参考になりました。
Nuxt.jsでAPIサーバを構築
サーバ側の構築と開発環境ができたので、あとはNuxt.jsをつかってアプリを作っていきます。
- Nuxt.jsはSSRモードで構築するとserverMiddlewareが使えます。
- サーバ側で動作する共通処理を実装できるので、これをつかって簡単なAPIサーバーが構築できます。
- 他のフレームワークや外部のサーバーを使わなくても、GAEとNuxt.jsだけで全部できるのでお手軽です。
serverMiddleware
Nuxt.js serverMiddlewareのドキュメント
カスタム API エンドポイント
を参考に作ります。
- サンプルコードのままだと、express周りの使い方がすこし古いようでしたので新しいバージョンに合わせて修正しました。
- ついでにTypeScriptで書き直しました
import express from 'express'
const app = express()
app.use(express.urlencoded({ extended: true }))
app.all('/getJSON', (_req: express.Request, res: express.Response) => {
res.json({ data: 'hello world' })
})
module.exports = app
Nuxtの設定ファイルを記述
serverMiddleware: [
{ path: "/api", handler: "~/server-middleware/rest.ts" },
],
これで、/api/getJSON
がAPIサーバーとしてルーティングされて、JSONを返すようになりました。
{
"data" : "hello world"
}
簡単なAPIサーバーならNuxtだけで作れます。
さいごに
とりあえず基本的なところのみでDBとの接続とかもしたんですがまとめていません。
GAEとNuxt.jsだけでウェブアプリケーションとその開発環境がつくれそうです。
いまさらだけどクラウドって楽しいですね。いろいろいじっていきたいです。