🐕
Next.js 14をAWS Lambdaにデプロイしてサーバーレス化する方法
環境
- wsl (Ubuntu)
- Docker version 27.0.3, build 7d4bcd8
- Node v18.20.4
- aws-cli aws-cli/2.17.13 Python/3.11.9 Linux/5.15.153.1-microsoft-standard-WSL2 exe/- x86_64.ubuntu.22
今回作成するネットワーク構成図
ECR リポジトリの作成
今回はプライベートリポジトリを作成しました。
Next.jsのプロジェクトを作成
wsl
cd ~
mkdir next-demo-app
cd next-demo-app
npx create-next-app@latest .
Standaloneモードでビルドできるようにする
next.config.mjs
/** @type {import('next').NextConfig} */
const nextConfig = {
output: "standalone",
};
export default nextConfig;
Dockerイメージを作り、ECRにPush
Dockerfileを作成します。
Dockerfile
FROM node:18-alpine AS base
FROM base AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app
COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./
RUN \
if [ -f yarn.lock ]; then yarn --frozen-lockfile; \
elif [ -f package-lock.json ]; then npm ci; \
elif [ -f pnpm-lock.yaml ]; then yarn global add pnpm && pnpm i --frozen-lockfile; \
else echo "Lockfile not found." && exit 1; \
fi
FROM base AS builder
WORKDIR /app
COPY /app/node_modules ./node_modules
COPY . .
RUN yarn build
FROM base AS runner
# Install Lambda Web Adapter
COPY /lambda-adapter /opt/extensions/lambda-adapter
ENV PORT=3000
WORKDIR /app
ENV NODE_ENV production
COPY /app/public ./public
COPY /app/.next/standalone ./
COPY /app/.next/static ./.next/static
EXPOSE 3000
ENV PORT 3000
CMD ["node", "server.js"]
ECRにPush
wsl
aws sso login
aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin <XXXXXXXXXXXX>.dkr.ecr.ap-northeast-1.amazonaws.com
docker build -t next-demo-app .
docker tag next-demo-app:latest <XXXXXXXXXXXX>.dkr.ecr.ap-northeast-1.amazonaws.com/next-demo-app:latest
docker push <XXXXXXXXXXXX>.dkr.ecr.ap-northeast-1.amazonaws.com/next-demo-app:latest
うまくいけば以下のように表示されます。
Lambda関数を作成
オプションからコンテナイメージ
を選びます。
コンテナイメージURI
にはECRにPushしたコンテナイメージを選んでください。
メモリを設定
設定
->一般設定
->編集
からメモリを256
MBに変更
関数URLを作成
設定
->関数 URL
->関数 URL を作成
をクリック
以下のように設定して保存する。
認証タイプ
: AWS_IAM
呼び出しモード
: RESPONSE_STREAM
API Gatewayの設定
API を作成
->HTTP API
の構築
統合を追加
をクリックしてLambda
を選択
作成したLambda関数を選択し、API名を入力して次へ
をクリック
ルートの設定
リソースパス
を$default
に変更して確認して作成
をクリックして作成
->をクリック
確認画面
確認
作成したAPI Gatewayのエンドポイントにアクセスできれば問題ないです。
Amplifyを使わずにLambdaにした理由
- AmplifyにデプロイしたNext.js(SSR)から直接s3にアップロードできない。
- AmplifyはVPCのサブネット内で実行できないがLambdaはできる。
余談
public/*
をs3に置いてCloudFrontを通してアクセスさせるようにすればLambdaの実行回数を大幅に削ることができそうなので、時間があれば記事を書きます。
参考
Discussion