こんにちは。駅メモエンジニアの id:kawa-mfです。
アワメモ公式サイトで、Nuxt2からNuxt3に移行しました。
しかし、Nuxt3をAWS Serverlessにデプロイする際にLambdaの制限容量を超えてしまい、ECRを利用することで解決したので、こちらについて書いていきます。
経緯
移行以前より、Lambdaの制限容量である250MB中、240MB以上を使用していました
Nuxt2からNuxt3から移行するにあたり、Lambdaの制限容量である250MBを超えてしまいました
元の構成は以下のようになっていました
Nuxt3へ移行するにあたり、既存のパッケージの更新や置換を行いました
結果、Lambdaの制限容量を超えてしまいました
(Nuxt2の時から、残り数MBみたいな状態が続いていて、制限容量を超えるのは時間の問題でした...)
容量を圧迫した主な原因としては、依存しているパッケージの更新などです
Lambdaの制限容量が超えてしまい、回避策として候補に上がったものについて
- AWS Serverlessの利用を中止し、AWS Amplifyに移行する
- AWS Serverlessのv4から有料になるので、別のものに移行したいということから、候補に上がりました
- しかし、弊社の運用ポリシーの観点から、使用することができませんでした
- Elastic Container Registryの導入
- 元の構成を大きく変える必要がなかった
- 弊社の別のプロジェクトで導入経験があった
- 今後の拡張性を考えて、ECRを導入することにしました
ECRを導入後の構成
上記の問題を解消するためにECR (Elastic Container Registry) を導入しました 導入した結果、以下のような構成に変わりました
元々、S3にはビルド後のファイルや画像などが配置されていました
その全てをECRに移したので、S3は廃止し、ECRからこれらの情報を取得するように変更しました
実際に変更したコード
アワメモ公式サイトのデプロイでは元から、CodeBuildを使用していました
今回は、CodeBuildからDockerのビルドも追加で行うように変更しました
以下では、Serverless.yml、Dockerfile、buildspec.ymlの変更点について説明します
Serverlessの調整
変更前
functions: handler: name: function-handler handler: .nuxt/dist/serverless.handler # memorySizeなどの他の設定
変更後
functions: handler: name: function-handler package: packageType: Image image: 'ECRのurl:latest' # latestを指定 url: true
上記には記述していないのですが、S3を使用しなくなったので、それに関連するものを削除しました
他にも、esbuildの導入、functions内のeventsやCacheBehaviorsの調整といった細かい修正は行なっています
Dockerfileの追加
こちらはECRの導入にあたり、新しく作成しました nuxt.config.tsで出力先のディレクトリは、lambda-distに変更しています
FROM public.ecr.aws/lambda/nodejs:18 as base RUN npm install -g yarn@1.22.21 ENV NODE_ENV $NODE_ENV # ----- builder FROM base AS builder WORKDIR /work COPY ./package.json ./yarn.lock ./ RUN yarn install # Copy remaining files for build COPY . . # Build the application RUN yarn build # ----- app FROM base WORKDIR ${LAMBDA_TASK_ROOT} COPY --from=builder /work/lambda-dist ${LAMBDA_TASK_ROOT}/lambda-dist COPY --from=builder /work/.nuxt ${LAMBDA_TASK_ROOT}/.nuxt COPY --from=builder /work/node_modules ${LAMBDA_TASK_ROOT}/node_modules CMD ["lambda-dist/server/index.handler"]
buildspecの調整
一部抜粋したものです
($
から始まるのは環境変数です)
phases: pre_build: commands: - aws ecr get-login-password --region ECRを置いているリージョン | docker login --username AWS --password-stdin $ACCOUNT build: commands: - yarn - docker build -t $ECR_IMAGE_NAME . # dockerビルド - docker tag $ECR_IMAGE_NAME:$ECR_TAG $ACCOUNT/$ECR_IMAGE_NAME:$ECR_TAG # ECRへpush post_build: commands: - docker push $ACCOUNT_ID.dkr.ecr.ap-northeast-1.amazonaws.com/$ECR_IMAGE_NAME:$ECR_TAG - yarn global add serverless@3.38.0 - sls deploy --verbose - aws cloudfront create-invalidation --distribution-id $DISTRIBUTION_ID --paths "/*"
まとめ
- AWS Amplifyは運用ポリシーの関係上、使用することができなかった
- ECRの導入
- Lambdaの制限容量を気にする必要がなくなった
- 弊社で導入実績があったため、導入に際してセキュリティなど考えることが少なかった
今後は、Nuxt2からNuxt3へ移行するにあたり苦戦した点や、AWS Serverlessのv4から有料になるにあたり、対応したことについては機会があれば書こうと考えています。
※ 一部の記述を訂正しました (2025/05/14 更新)