Mobile Factory Tech Blog

技術好きな方へ!モバイルファクトリーのエンジニアたちが楽しい技術話をお届けします!

Lambdaの制限容量を超えてしまい、ECRを導入した話

こんにちは。駅メモエンジニアの 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 更新)