背景
nuxtで作ったアプリをAWSにデプロイする方法について調べていたところ、nuxt-serverlessというものがあることを知ったので、お勉強。
nuxt-serverless
とりあえず、READMEを翻訳。
「サーバーレスフレームワークを使用したAWSサーバーレススタック(Lambda + API Gateway + S3)上のNuxt.jsサーバーレスサーバー側レンダリングスターター」
とのこと。
ざっと中のコードを見た感じ、nuxtプロジェクトのテンプレートになっていて、ここにServerless Frameworkの設定ファイル等があらかじめ配備されている形になっていました。
使い方としては、githubのコードをclone(もしくはダウンロード)してきたものをベースに、srcの中を編集してnuxtアプリを作成し、serverless.ymlを編集して自分用のデプロイ設定に変更後、yarn deploy:??? コマンドでビルドとデプロイを実行する感じでしょうか。
nuxt-serverless を試してみる
事前準備として、AWSの設定 (その前にAWS CLIをインストールしていなければインストール)
※あらかじめAWSにアカウント作っておく必要もあります。
aws configure
Githubからnuxt-serverlessをクローン
git clone https://github.com/tonyfromundefined/nuxt-serverless.git
インストール
cd nuxt-serverless
yarn install
そのままローカルで動かしてみる
yarn dev
ブラウザでアクセスすると下のような感じ。
「typescript」と「nuxt」のリンクを押下すると下に遷移。
続いて、デプロイに向けた設定。
ちょっと長いので、serverless.ymlを上から見ていく。
service: nuxt-serverless
plugins:
- serverless-s3-sync
- serverless-apigw-binary
- serverless-dotenv-plugin
package:
individually: true
excludeDevDependencies: true
provider:
name: aws
runtime: nodejs10.x
stage: ${opt:stage, 'dev'}
region: us-east-1
custom:
#######################################
# Unique ID included in resource names.
# Replace it with a random value for every first distribution.
# https://www.random.org/strings/?num=1&len=6&digits=on&loweralpha=on&unique=on&format=html&rnd=new
stackId: lxpmd3
#######################################
(続く)
サービス名はデプロイするサービスに合わせて変更。(今回はそのままにしておく)
リージョンは東京に変更しておく。
region: ap-northeast-1
stackIdにランダムな文字を指定。
今回は指定の通りに下記で生成して設定。
https://www.random.org/strings/?num=1&len=6&digits=on&loweralpha=on&unique=on&format=html&rnd=new
ちなみにこのstackIdで各リソースの一意性を担保しているようなので、必ず変更が必要。
stackId: l7o0rg
他はそのままで良さそう。
続きを見ていく。次はS3関連の設定っぽい。
クライアント系のリソース(.nuxt/dist/client)は、S3に入れているのが分かる。
変更は必要なさそう。
(続き)
buckets:
ASSETS_BUCKET_NAME: ${self:service}-${self:custom.stackId}-${self:provider.stage}-assets
STATIC_BUCKET_NAME: ${self:service}-${self:custom.stackId}-${self:provider.stage}-static
s3Sync:
- bucketName: ${self:custom.buckets.ASSETS_BUCKET_NAME}
localDir: .nuxt/dist/client
- bucketName: ${self:custom.buckets.STATIC_BUCKET_NAME}
localDir: static
apigwBinary:
types:
- '*/*'
(続く)
以降はLambda関連の設定。
実行環境とか、Lambdaに配備するファイルとかを指定している。
ここもそのままで良さそう。
(続き)
functions:
renderer:
name: ${self:service}-${self:custom.stackId}-${self:provider.stage}-renderer
handler: .nuxt/dist/serverless.handler
memorySize: 2048
timeout: 30
environment:
NODE_ENV: production
package:
include:
- .nuxt/dist/serverless.js
- .nuxt/dist/server/**
exclude:
- .nuxt/**
- src/**
- app.js
- nuxt.config.js
- nuxt.d.ts
- README.md
- server.js
- serverless.js
- serverless.yml
- tsconfig.json
- tslint.json
- webpack.config.js
- yarn-error.log
(続く)
次に記載されているのは、内容的にAPI Gateway系の設定かな。ここもそのままで。
(続き)
events:
- http:
path: /
method: any
- http:
path: /{proxy+}
method: any
- http:
path: /_nuxt/{proxy+}
method: any
integration: http-proxy
request:
uri: https://${self:custom.buckets.ASSETS_BUCKET_NAME}.s3.${self:provider.region}.amazonaws.com/{proxy}
parameters:
paths:
proxy: true
- http:
path: /static/{proxy+}
method: any
integration: http-proxy
request:
uri: https://${self:custom.buckets.STATIC_BUCKET_NAME}.s3.${self:provider.region}.amazonaws.com/{proxy}
parameters:
paths:
proxy: true
(続く)
以降は、assets用のバケット作成とポリシー割り当て。
中身はAWS CloudFormationの書式のようですね。
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/AWS_S3.html
このあたりもそのままで大丈夫そう。
(続き)
resources:
Resources:
ClientAssetsBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: ${self:custom.buckets.ASSETS_BUCKET_NAME}
CorsConfiguration:
CorsRules:
-
AllowedOrigins:
- '*'
AllowedHeaders:
- '*'
AllowedMethods:
- GET
- HEAD
- PUT
- POST
- DELETE
MaxAge: 3000
ExposedHeaders:
- x-amz-server-side-encryption
- x-amz-request-id
- x-amz-id-2
ClientAssetsBucketPolicy:
Type: AWS::S3::BucketPolicy
Properties:
Bucket:
Ref: ClientAssetsBucket
PolicyDocument:
Version: '2012-10-17'
Statement: [
{
Action: ['s3:GetObject'],
Effect: 'Allow',
Resource: {
Fn::Join: ['', ['arn:aws:s3:::', { Ref: 'ClientAssetsBucket' }, '/*']],
},
Principal: '*'
},
]
(続く)
続いてstatic用のバケット作成とポリシー割り当て。上とほぼ同じ。変更もなし。
(続き)
ClientStaticBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: ${self:custom.buckets.STATIC_BUCKET_NAME}
CorsConfiguration:
CorsRules:
-
AllowedOrigins:
- '*'
AllowedHeaders:
- '*'
AllowedMethods:
- GET
- HEAD
- PUT
- POST
- DELETE
MaxAge: 3000
ExposedHeaders:
- x-amz-server-side-encryption
- x-amz-request-id
- x-amz-id-2
ClientStaticBucketPolicy:
Type: AWS::S3::BucketPolicy
Properties:
Bucket:
Ref: ClientStaticBucket
PolicyDocument:
Version: '2012-10-17'
Statement: [
{
Action: ['s3:GetObject'],
Effect: 'Allow',
Resource: {
Fn::Join: ['', ['arn:aws:s3:::', { Ref: 'ClientStaticBucket' }, '/*']],
},
Principal: '*'
},
]
結局、変更したのはregionとstackIdだけ。
設定が完了したので、デプロイコマンドを実行してみる。
> yarn deploy:dev
yarn run v1.22.4
$ sls deploy --stage dev
Serverless: DOTENV: Loading environment variables from .env.development:
Serverless: - NUXT_APP_STAGE
Serverless: - NUXT_APP_GRAPHQL_ENDPOINT
Serverless: - NUXT_APP_VERSION
Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Creating Stack...
Serverless: Checking Stack create progress...
.....
Serverless: Stack create finished...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service renderer.zip file to S3 (24.85 MB)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
...............................................................
Serverless: Stack update finished...
Service Information
service: nuxt-serverless
stage: dev
region: ap-northeast-1
stack: nuxt-serverless-dev
resources: 21
api keys:
None
endpoints:
ANY - https://lyktihubdl.execute-api.ap-northeast-1.amazonaws.com/dev/
ANY - https://lyktihubdl.execute-api.ap-northeast-1.amazonaws.com/dev/{proxy+}
ANY - https://lyktihubdl.execute-api.ap-northeast-1.amazonaws.com/dev/_nuxt/{proxy+}
ANY - https://lyktihubdl.execute-api.ap-northeast-1.amazonaws.com/dev/static/{proxy+}
functions:
renderer: nuxt-serverless-l7o0rg-dev-renderer
layers:
None
S3 Sync: Syncing directories and S3 prefixes...
.........
S3 Sync: Synced.
Serverless Enterprise: Run `serverless login` and deploy again to explore, monitor, secure your serverless project for free.
Done in 118.22s.
2分ほどでデプロイ完了。
表示されているURLにアクセスすると、
ちゃんとメイン画面が表示された。
ただ、画面に表示されている「typescript」と「nuxt」のリンク先が正しく表示できず。
READMEにも下のように書いてあるし、URLに{stage}が入ることでルーティングに失敗しているものと思う。
- Auto generated URL https://*.execute-api.{region}.amazonaws.com/{stage}/ will result in a JavaScript error. (routing problem) Please use the Custom Domain.
URLを~/typescriptから~/dev/typescriptに変更して、直接ブラウザのアドレスバーに入れたら表示された。
最後に、作った環境を消しておく。
> yarn undeploy:dev
yarn run v1.22.4
$ sls remove --stage dev
Serverless: DOTENV: Loading environment variables from .env.development:
Serverless: - NUXT_APP_STAGE
Serverless: - NUXT_APP_GRAPHQL_ENDPOINT
Serverless: - NUXT_APP_VERSION
S3 Sync: Removing S3 objects...
...
S3 Sync: Removed.
Serverless: Getting all objects in S3 bucket...
Serverless: Removing objects in S3 bucket...
Serverless: Removing Stack...
Serverless: Checking Stack removal progress...
.......................................
Serverless: Stack removal finished...
Done in 24.49s.
S3バケットも消える。
参考にしたサイト