Next.jsをLambdaにデプロイする方法についての説明。
今回のプロジェクトは cdk用ディレクトリ next-cdk の中に、Next.jsのプロジェクトディレクトリ next-app が存在する構成です。
next-cdk --- package.json (CDK用) |- Dockerfile (デプロイ用) |- lib -------- next-cdk-stack.ts | |- next-app --- package.json (Next.js用) |- .next (ビルド成果物用) |- src --- appプロジェクトの作成方法は以下を参照
Dockerイメージでデプロイ
以下を参考にDockerイメージによるデプロイを行います。
Next.jsをLambdaで動作させる場合、AWS Lambda Web Adapterが必要となります。 AWS Lambda Web Adapter は、Lambda ランタイムが受け取ったイベントをHTTPリクエストに変換し、Webサーバーにリクエストします。 Dockerイメージでデプロイする場合、Dockerfileに以下を追加する必要があります。
COPY --from=public.ecr.aws/awsguru/aws-lambda-adapter:0.7.0 /lambda-adapter /opt/extensions/lambda-adapter
例 Dockerfile
# 以下を参考にして作成 # https://aws.amazon.com/jp/blogs/news/implementing-ssr-streaming-on-nextjs-with-aws-lambda-response-streaming/ FROM node:20-alpine AS base FROM base AS builder RUN apk add --no-cache libc6-compat WORKDIR /next-app COPY ./next-app/node_modules ./node_modules COPY --from=public.ecr.aws/awsguru/aws-lambda-adapter:0.7.0 /lambda-adapter /opt/extensions/lambda-adapter ENV NODE_ENV=production ENV PORT=3000 EXPOSE 3000 WORKDIR /next-app COPY ./next-app/public ./public COPY ./next-app/.next/standalone ./ COPY ./next-app/.next/static ./.next/static CMD ["node", "server.js"]
CDKスタック
ここではLambdaでの動作確認を簡単にするため、Lambda Function URLs(関数URL)を使って直接アクセスできるようにします。
DockerイメージでLambdaにデプロイする場合、DockerImageFunctionクラスを使います。 fromImageAssetでDockerfileのあるディレクトリを指定します。
import * as cdk from 'aws-cdk-lib'; import * as lambda from 'aws-cdk-lib/aws-lambda'; import { Construct } from 'constructs'; import path = require('path'); export class NextCdkStack extends cdk.Stack { constructor(scope: Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); this.createLambda(); } private createLambda() { const lambdaDockerFunction = new lambda.DockerImageFunction(this, 'NextCdkDockerFunctionn', { code: lambda.DockerImageCode.fromImageAsset(path.resolve(__dirname, '../')), functionName: 'NextCdkDockerFunctionn', }); const funcUrl = lambdaDockerFunction.addFunctionUrl({ authType: lambda.FunctionUrlAuthType.NONE, cors: { allowedMethods: [lambda.HttpMethod.ALL], allowedOrigins: ["*"], }, }); new cdk.CfnOutput(this, 'FuntionUrl', { value: funcUrl.url }); } }
デプロイが成功するとDockerイメージは Amazon ECR (Elastic Container Registry)に登録されます。
参考
ビルド+デプロイ用コマンド
Next.jsの実行環境は npm run build コマンドでビルドしてその成果物をDockerイメージにコピーすることで作成します。 そのため、CDK用package.jsonにビルドとデプロイをまとめて実行するコマンドを追加します。また、CDKのDIFFコマンドも追加しておきます。
例 CDK用package.jsonのscripts
"scripts": { "cdk": "cdk", "cdk:diff": "cd next-app && npm run build && cd ../ && cdk diff", "cdk:deploy": "cd next-app && npm run build && cd ../ && cdk deploy" },
最新のビルドとデプロイを行う場合、以下のDIFFコマンドを先に実行して差分やエラーが無いかを確認しておきます。
npm run cdk:diff
問題なければ以下で最新のビルドとデプロイを実行します。
npm run cdk:deploy