Closed27

Next.jsのアプリをLambda Web Adapter を利用してホスティングしてみる

りょたりょた

セットアップ

next のバージョンを合わせる。

npx create-next-app
npm remove next
npm i next@13.4.2
りょたりょた

デプロイ

 Stack Name [sam-app]: next-lambda-streaming
        AWS Region [ap-northeast-1]: ap-northeast-1
        #Shows you resources changes to be deployed and require a 'Y' to initiate deploy
        Confirm changes before deploy [y/N]: y
        #SAM needs permission to be able to create roles to connect to the resources in your template
        Allow SAM CLI IAM role creation [Y/n]: n
        Capabilities [['CAPABILITY_IAM']]: 
        #Preserves the state of previously provisioned resources when an operation fails
        Disable rollback [y/N]: y
        StreamingNextjsFunction Function Url has no authentication. Is this okay? [y/N]: y
        Save arguments to configuration file [Y/n]: Y
        SAM configuration file [samconfig.toml]: samconfig.toml
        SAM configuration environment [default]: default
        Create managed ECR repositories for all functions? [Y/n]: Y
りょたりょた

公式Example
https://github.com/awslabs/aws-lambda-web-adapter/tree/main/examples/nextjs-response-streaming

npx create-next-app@latest nextjs-response-streaming --use-npm --example "https://github.com/awslabs/aws-lambda-web-adapter/tree/main/examples/nextjs-response-streaming"
りょたりょた
/** @type {import('next').NextConfig} */
const nextConfig = {
  experimental: {
    appDir: true,
  },
  compress: true,
  output: "standalone", // 追加
  images: {
    remotePatterns: [
      {
        protocol: "https",
        hostname: "images.unsplash.com"
      }
    ]
  }
}

module.exports = nextConfig

りょたりょた

初回のみ

sam deploy --guided

2回目以降
sam deploy 
Stack Name [sam-app]: nextjs-response-streaming
        AWS Region [ap-northeast-1]: ap-northeast-1
        #Shows you resources changes to be deployed and require a 'Y' to initiate deploy
        Confirm changes before deploy [y/N]: y
        #SAM needs permission to be able to create roles to connect to the resources in your template
        Allow SAM CLI IAM role creation [Y/n]: n
        Capabilities [['CAPABILITY_IAM']]: 
        #Preserves the state of previously provisioned resources when an operation fails
        Disable rollback [y/N]: y
        StreamingNextjsFunction Function Url has no authentication. Is this okay? [y/N]: y
        Save arguments to configuration file [Y/n]: Y
        SAM configuration file [samconfig.toml]: samconfig.toml
        SAM configuration environment [default]: default
        Create managed ECR repositories for all functions? [Y/n]: Y
りょたりょた

でしてAPI Gateway + Lambdaで動かす意味は?とも思えてきてしまうのが正直なところ。
もちろんPay as you goなプライシングモデルによってコストとしてゼロスタートできることやスケーリングというメリットはあるものの、このソリューションがコンテナイメージで動かす前提であるためDockerfileを書かなければいけないわけで、それならもう普通にAWS Fargateとかでいいじゃないかって思ってしまう。

https://www.keisuke69.net/entry/2022/12/29/135620

りょたりょた

活用方法
ここまでで、Lambda Web Adapter の仕組みや使い方、また性能的にも十分実用的であることを確認しました。最後に Web Adapter の活用方法をいくつか考えてみました:
既存のコンテナアプリを Lambda 化することで、アイドル時の利用料金や管理の手間を減らす。Lambda Function URL なども組み合わせれば、最小労力で Web アプリを Lambda にデプロイし、ちょっとしたサービスを提供することができそうです。
コンテナアプリをそのまま安価なサーバーレスで動かすことができ、高いスケーラビリティも確保できます。考え方によっては、AWS App Runner と同じような使い方ができると言えるかもしれません。
従来 Lambda 上で動かすことが困難だった HTTP アプリ、例えば nginx や HAProxy などもサーバーレス化できるようになります。実用性に一考の余地はありますが、技術的にはサーバーレスロードバランサーやサーバーレスリバースプロキシといった活用も考えられるでしょう。
今コンテナで動いている Web アプリをそのまま Lambda 上でも動かし、突発的な負荷を Lambda に逃がすというのはいかがでしょうか。通常コンテナより Lambda の方がスケールアウトが速いため、システムのスパイク耐性をより高めることができるでしょう。

https://aws.amazon.com/jp/builders-flash/202301/lambda-web-adapter/?awsf.filter-name=*all

りょたりょた
りょたりょた

なお、AWS Lambda ではデプロイされるパッケージのサイズに 250MB のクォータが設けられており、注意が必要です。

assetsの配信は別で用意する必要がある。

りょたりょた

Lambda context を転送してくれそう。

https://github.com/awslabs/aws-lambda-web-adapter#lambda-context

Lambda Context is an object that Lambda passes to the function handler. This object provides information about the invocation, function, and execution environment. You can find a full list of properties accessible through the Lambda Context here

Lambda Web Adapter forwards this information to the web application in a Http Header named "x-amzn-lambda-context". In the web application, you can retrieve the value of this http header and deserialize it into a JSON object. Check out Express.js in Zip on how to use it.

このスクラップは2023/12/02にクローズされました