前回、以下のリポジトリからカスタムドメインの利用を外した構成で、Nuxt.js(v2.2.0)+TypeScriptのアプリがAPI Gateway+AWS Lambdaにデプロイできることを確認しました。
Nuxt.js(v2.2.0)+TypeScriptなアプリをAWS Lambda+αにデプロイしてみた
https://cloudpack.media/44795
jeehyukwon/nuxt-serverless: Nuxt.js Serverless SSR Starter on AWS (Lambda + API Gateway + S3) with Serverless Framework
https://github.com/jeehyukwon/nuxt-serverless
今回は、以下のような記事を発見してしまったので、S3を外した構成を試してみます。発見したからには仕方がないです。やってみます。
Serverless-Side Rendering With AWS Lambda & NuxtJS
https://medium.com/@fernalvarez/serverless-side-rendering-with-aws-lambda-nuxtjs-b94d15782af5
手順
環境構築
GitHubに今回のソースをアップしていますので、よければご参考ください。
https://github.com/kai-kou/nuxt-serverless/tree/feature/no-use-s3
前回フォークしたリポジトリを利用します。
kai-kou/nuxt-serverless: Nuxt.js Serverless SSR Starter on AWS (Lambda + API Gateway + S3) with Serverless Framework
https://github.com/kai-kou/nuxt-serverless
> git clone https://github.com/kai-kou/nuxt-serverless.git > cd nuxt-serverless > npm install
必要となるライブラリのインストールと、不要となるライブラリをアンインストールします。
> npm install --save-dev serverless-apigw-binary > npm install --save aws-serverless-express > npm uninstall --save serverless-http > npm uninstall --save-dev serverless-s3-sync
serverless.yaml
を編集します。S3に関する定義を削除、LambdaとAPI Gatewayで静的ファイルが返せるように定義を追加しています。service
やregion
は任意でどうぞ。
serverless.yml
service: nuxt-serverless # 1. Edit whole service name provider: name: aws runtime: nodejs8.10 stage: ${opt:stage, 'dev'} region: ap-northeast-1 # 2. Edit AWS region name environment: NODE_ENV: production custom: serverless-offline: port: 4000 apigwBinary: types: - '*/*' package: exclude: - src/** include: - serverless.yml functions: nuxt-renderer: handler: handler.render memorySize: 512 timeout: 30 events: - http: path: / method: ANY cors: true - http: path: /{proxy+} method: ANY cors: true plugins: - serverless-offline - serverless-apigw-binary
実装
handler.js
の実装を分割します。
ほぼ、記事通りの実装となります。
handler.js
const awsServerlessExpress = require('aws-serverless-express') const app = require('./server') const binaryMimeTypes = [ 'application/javascript', 'application/json', 'application/octet-stream', 'application/xml', 'font/eot', 'font/opentype', 'font/otf', 'image/jpeg', 'image/png', 'image/svg+xml', 'text/comma-separated-values', 'text/css', 'text/html', 'text/javascript', 'text/plain', 'text/text', 'text/xml' ] const server = awsServerlessExpress.createServer(app, null, binaryMimeTypes) module.exports.render = (event, context) => awsServerlessExpress.proxy(server, event, context)
server.js
にExpressの実装を引っ越しました。ポイントは/_nuxt
と/static
へのアクセス時にS3にリダイレクトさせていたのを、直接ファイルを返すようにしている点です。
前回同様に、ステージ名のパス対応も入れています。
server.js
const express = require('express') const {Nuxt} = require('nuxt') const path = require('path') const awsServerlessExpressMiddleware = require('aws-serverless-express/middleware') const app = express() app.use(awsServerlessExpressMiddleware.eventContext()) app.use('/_nuxt', express.static(path.join(__dirname, '.nuxt', 'dist', 'client'))) app.use('/static', express.static(path.join(__dirname, 'static'))) let config = require('./nuxt.config.js') const nuxt = new Nuxt(config) app.use((req, res) => { req.url = `${config.router.base}${req.url}`.replace('//', '/') nuxt.render(req, res) }) module.exports = app
デプロイ
デプロイしてみます。
> npm run sls:create (略) Entrypoint app = 55e8f003a83a598dd113.js 5e45cc8df25adbaac94b.js 1d1bc122ddb9c7b7f271.css 1417c3d6af1ef683305c.js [15:20:26] Compiling server [15:20:31] Compiled server in 5s Hash: f66c1442df8e32ec8ab4 Version: webpack 4.25.1 Time: 4754ms Built at: 2018-11-13 15:20:31 Asset Size Chunks Chunk Names server-bundle.json 213 KiB [emitted] Entrypoint app = server-bundle.js (略) Serverless: Stack update finished... Service Information service: nuxt-serverless stage: dev region: ap-northeast-1 stack: nuxt-serverless-dev api keys: None endpoints: ANY - https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/dev/ ANY - https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/dev/{proxy+} functions: nuxt-renderer: nuxt-serverless-dev-nuxt-renderer
動作確認
デプロイができたら、ブラウザでアクセスしています。
https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/dev/
やったぜ。
ハマりどころ
API Gatewayのパス指定に気をつけよう
今回は参考にした記事だと、serverless.yml
events
にhttp
設定が1つだけですが、それだとhttps://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/dev/
にアクセスしても、API GatewayからAWS Lambdaへイベントが発火せず、{"message":"Missing Authentication Token"}
となりました。ここは前回参考にした記事の設定のままだとうまくいきました。
OK
events: - http: path: / method: ANY cors: true - http: path: /{proxy+} method: ANY cors: true
だめ。1時間くらい悩んだ
events: - http: path: /{proxy+} method: ANY cors: true
これもだめ。もうだめだ
events: - http: ANY {proxy+}
タイムアウトエラーが発生したらyarn
を利用する
npm
でライブラリをインストールしていると、デプロイできても、URLへアクセスするとタイムアウトエラーになることがありました。その場合には、yarn
でライブラリをインストールし直すとうまく動きました。
> rm -rf node_modules/ > npm install -g yarn # yarnがインストールされていなかったら > yarn > yarn build > sls deploy
注意点
注意点としては、静的ファイルが多くなるとAWS Lambdaのアップロード制限に引っかかる可能性があるかもしれません。
AWS Lambda の制限 – AWS Lambda
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/limits.html
AWS Lambda デプロイメントの制限
Lambda 関数デプロイパッケージのサイズ (圧縮 .zip/.jar ファイル) : 50 MB
リージョンあたりの、アップロードできるすべてのデプロイパッケージの合計サイズ : 75 GB
デプロイパッケージ (非圧縮 .zip/.jar サイズ) に圧縮できるコード/依存関係のサイズ: 250 MB
まとめ
シンプルなSSR対応のサービスを提供するにはこちらのほうがシンプルですね。
プロジェクト次第で使い分けが良さそうです。
参考
Serverless-Side Rendering With AWS Lambda & NuxtJS
https://medium.com/@fernalvarez/serverless-side-rendering-with-aws-lambda-nuxtjs-b94d15782af5
Nuxt.js(v2.2.0)+TypeScriptなアプリをAWS Lambda+αにデプロイしてみた
https://cloudpack.media/44795
jeehyukwon/nuxt-serverless: Nuxt.js Serverless SSR Starter on AWS (Lambda + API Gateway + S3) with Serverless Framework
https://github.com/jeehyukwon/nuxt-serverless
元記事はこちら
「Nuxt.js(v2.2.0)+TypeScriptなアプリをAWS Lambda+αにデプロイしてみた(S3なし版)」