Nuxt & Lambda & ApiGateway

概要

Nuxtを、Lambda x ApiGateway で動かしてみた。

github.com

参考にしたサイト

ありがとうございます!

Nuxt.jsをAWS Lambda上で動かす.サーバレス・サーバサイドレンダリング - Qiita

GitHub - tonyfromundefined/nuxt-serverless: Nuxt.js Serverless SSR Starter on AWS (Lambda + API Gateway + S3) with Serverless Framework

方法

NuxtのPJを作成

$ yarn create create-nuxt-app <project-name>

で作成する。

expressを選ぶことだけ忘れずに。

npm package 追加

yarn add aws-lambda aws-serverless-express

server/index.js を修正

const awsServerlessExpress = require('aws-serverless-express')

# 省略

let server = undefined;
const binaryMimeTypes = [
  'application/javascript',
  'application/json',
  'application/octet-stream',
  'application/xml',
  'font/eot',
  'font/opentype',
  'font/otf',
  'image/x-icon',
  'image/jpeg',
  'image/png',
  'image/svg+xml',
  'text/comma-separated-values',
  'text/css',
  'text/html',
  'text/javascript',
  'text/plain',
  'text/text',
  'text/xml'
]

exports.handler = (event, context) => {
  start().then((app) => {
    if (server === undefined) {
      server = awsServerlessExpress.createServer(app, null, binaryMimeTypes)
    }
    awsServerlessExpress.proxy(server, event, context)
  })
}

serverless.yml を作成

先にserverless framework を利用可能にしておく。

Serverless Frameworkの使い方まとめ - Qiita

service: nuxt-lambda-test

provider:
  name: aws
  runtime: nodejs12.x
  stage: dev
  region: ap-northeast-1

custom:
  buckets:
    ASSETS_BUCKET_NAME: nuxt-lambda-test-assets # S3のバケット名
  s3Sync: # S3を同期する時のパラメーター
    - bucketName: ${self:custom.buckets.ASSETS_BUCKET_NAME}
      bucketPrefix: assets/
      localDir: dist/dist/client
    - bucketName: ${self:custom.buckets.ASSETS_BUCKET_NAME}
      bucketPrefix: static/
      localDir: static/static # かっこ悪いですが...

functions:
  renderer:
    handler: server/index.handler
    memorySize: 512
    timeout: 5
    environment:
      NODE_ENV: development
    package:
      individually: true
      exclude:
        - '**'
      include: # 必要最低限だけ
        - server/**
        - dist/**
        - nuxt.config.js
    events:
      - http:
          path: /
          method: any
      - http:
          path: /{proxy+}
          method: any
      - http: # _nuxt 以下のファイルは、S3をみるように
          path: /_nuxt/{proxy+}
          # 省略
      - http: # 同じくstatic 以下のファイルは、S3をみるように
          path: /static/{proxy+}
          # 省略

    layers:
      - {Ref: MylayerLambdaLayer}

layers: # lambda layer を設定
  mylayer:
    path: layers

resources:
  Resources:
    ClientAssetsBucket: # S3 Bucketを作成
      # 省略

plugins: # S3にファイル同期のために必要
  - serverless-s3-sync

lambda layer の準備

$ yarn # node_modules を install

# lambda layer を利用するには、指定の位置にnode_modulesが必要。
# そのため必要なものをinstall
$ mkdir layers/nodejs/node_modules
$ yarn --production --modules-folder layers/nodejs/node_modules

staticフォルダ周りを微修正

# staticファイルの場所を変更する。
$ mkdir static/static
$ mv static/favicon.ico static/static

nuxt.config.js

# static ファイルのpathを /favicon.ico => /static/favicon.ico に変更
link: [{ rel: 'icon', type: 'image/x-icon', href: '/static/favicon.ico' }]

Deploy!!

$ yarn build
$ SLS_DEBUG=true sls deploy

# こちらでも可能
$ make deploy

ApiGatewayの設定

ApiGatewayで割り振られるドメインをそのまま使うと、stage名が入ってきて上手くパスが動かない。

なので、カスタムドメインを設定する必要がある。

API Gatewayのカスタムドメイン化がちょっとだけややこしかった話 | BeeX Technical Blog

試してないけど、CloudFrontを使ってもいけると思う。

終わり

記憶を思い出しながらやってるので、間違えているかもしれません...