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