Lambda Web AdapterでRemixアプリケーションをサーバーレス化してCDKでデプロイする

既存の Web フレームワークを Lambda に組み込む方法として Lambda Web Adapter というのがあります。

Lambda Web Adapter でウェブアプリを (ほぼ) そのままサーバーレス化する Lambda Web Adapter - 変化を求めるデベロッパーを応援するウェブマガジン | AWS
VM やコンテナ用に実装されたウェブアプリを、ほとんどそのまま Lambda でも動かせる AWS Lambda Web Adapter についてその使い方、仕組みや対応する Web フレームワーク、性能をご紹介します。
GitHub - awslabs/aws-lambda-web-adapter: Run web applications on AWS Lambda
Run web applications on AWS Lambda. Contribute to awslabs/aws-lambda-web-adapter development by creating an account on G...

その仕組みですが、API Gateway などの統合先から受信したイベントをフレームワークの手前にある Lambda Web Adapter のエントリポイントが HTTP リクエストに変換して、フレームワークに渡してくれる、というイメージで良さそうです。

公式の実装例では、Node.js であれば Next.js と Express.js が対応していますが、HTTP であればどのようなフレームワークも動作するはずです。

今回はこれを使って Remix アプリをサーバーレス化してみました。既に作ったものは GitHub にあげてあります。

GitHub - ShotaroMuraoka/cdk-serverless-remix: Remix アプリケーションを Lambda Web Adapter でサーバーレス化した CDK
Remix アプリケーションを Lambda Web Adapter でサーバーレス化した CDK. Contribute to ShotaroMuraoka/cdk-serverless-remix development by crea...

CDKの準備

デプロイの方法は CDK にしました。init で新しいプロジェクトを作成しておきます。

$ cdk --version
2.148.0 (build e5740c0)

$ cdk init app --language typescript

今回は HTTP リクエストを受け付けるので、API Gateway と統合します。Stack は以下からお借りしました。

import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import { Platform } from 'aws-cdk-lib/aws-ecr-assets';
import * as apigw from 'aws-cdk-lib/aws-apigatewayv2';
import { HttpLambdaIntegration } from 'aws-cdk-lib/aws-apigatewayv2-integrations';

export class MyLambdaStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);
    const handler = new lambda.DockerImageFunction(this, 'Handler', {
      code: lambda.DockerImageCode.fromImageAsset('./my-remix', { // Remix アプリケーションのディレクトリ名とする
        platform: Platform.LINUX_AMD64,
      }),
      memorySize: 256,
      timeout: cdk.Duration.seconds(30),
    });

    new apigw.HttpApi(this, 'Api', {
      apiName: 'MyLambdaRemix',
      defaultIntegration: new HttpLambdaIntegration('Integration', handler),
    });
  }
}

Remixアプリケーションの作成

CDK のプロジェクトルートで Remix アプリを作成します。

$ npx create-remix@latest

Remix アプリのルートに Dockerfile を作成します。Remix に対応した Dockerfile を作成したことがなかったので、以下を参考にそれっぽく書いてみました。

hackernews-remix-react/Dockerfile at main · clintonwoo/hackernews-remix-react
Hacker News clone written with universal TypeScript, using React and Remix. - clintonwoo/hackernews-remix-react
FROM node:22-bookworm-slim AS base

FROM base AS deps
RUN mkdir /app
WORKDIR /app

COPY package.json package-lock.json ./
RUN npm ci

FROM base AS builder

RUN mkdir /app
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .

ENV NODE_ENV production
RUN npm run build

FROM base AS runner

# lambda-web-adapter
COPY --from=public.ecr.aws/awsguru/aws-lambda-adapter:0.5.0 /lambda-adapter /opt/extensions/lambda-adapter

RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 remix

RUN mkdir /app
WORKDIR /app

RUN chown remix:nodejs ./
USER remix

COPY --from=builder --chown=remix:nodejs /app/node_modules ./node_modules
COPY --from=builder --chown=remix:nodejs /app/build ./build
COPY --from=builder --chown=remix:nodejs /app/public ./public
COPY --from=builder --chown=remix:nodejs /app/package.json /app/package-lock.json ./

ENV NODE_ENV production
ENV PORT 3000
EXPOSE 3000

CMD ["npm", "run", "start"]

ここでは Lambda Web Adapter のために難しい記述をする必要はありません。ローカルでも ECS でも動くコンテナイメージであれば、Lambda Web Adapter で動作するようです。

追記が必要なのは Lambda の extension を追加するというところのみです。

COPY --from=public.ecr.aws/awsguru/aws-lambda-adapter:0.5.0 /lambda-adapter /opt/extensions/lambda-adapter

また、デフォルトでは 8080 でポートを Listen しているので、変更する場合は PORT を指定します。

ENV PORT 3000

デプロイ

CDK のルートディレクトリでデプロイを実行します。

$ cdk deploy

管理コンソールから API Gateway の画面を確認すると、作成した API Gateway のエンドポイントが作成されています。

AWS の管理コンソールで API Gateway > API > MyLambdaRemixの画面を開いている。エンドポイントが有効になっており、リンクが表示されている

デフォルトのエンドポイントの URL をクリックして Remix アプリの画面が表示されていれば OK です。

Remix の初期の画面で、Welcome to Remix と表示されている

参考資料

Dockerを使わない、Remix / Next.js 14 など最新ウェブフレームワークのAWS完全サーバーレス構成と環境構築方法 | ブログ | Serverless Operations
SPA(Single Page Application)が主流だったフロントエンド開発トレンドがSSR(Server-side rendering)とエッジコンピューティングに向けた最適化が進むなど、...

タイトルとURLをコピーしました