🐈

AWS CDKを用いてRemixアプリケーションをLambdaにデプロイする

2024/07/30に公開

はじめに

この記事はこちらの記事の内容をAWS CDKに置き換えたものです。
cdkプロジェクトはTypeScriptで作成しています。

完成品はこちらのリポジトリにあります。

https://github.com/monjara/remix-cdk-lambda-example

必要なもの

  • CDK CLI
  • Node.js
  • Docker

階層構造

以下のような階層でプロジェクトを作成します。

.
├── remix-app/ # Remixのアプリケーション
│   ├── (Remixのファイル群)
│   ├── Dockerfile # buildしたアプリケーションを実行するためのDockerfile
│   └── run.sh # remix-serveを実行するスクリプト
└── cdk/ # CDKのプロジェクト

Remixプロジェクトのセットアップ

npx create-remix@latest

Remixアプリケーション起動用スクリプトの作成

remix-app配下にrun.shを作成して実行権限を付与します。
後述するDockerfileからCMDコマンドでこちらのファイルを実行します。

remix-app/run.sh
#!/bin/bash -x

HOST=0.0.0.0 HOME=/tmp exec npm run start

Dockerfileの作成

remix-app配下にDockerfileを作成します。

remix-app/Dockerfile
FROM public.ecr.aws/docker/library/node:20.9.0-slim as builder
WORKDIR /app
COPY . .
RUN npm ci && npm run build

FROM public.ecr.aws/docker/library/node:20.9.0-slim as runner
COPY --from=public.ecr.aws/awsguru/aws-lambda-adapter:0.8.3 /lambda-adapter /opt/extensions/lambda-adapter
ENV PORT=3000 NODE_ENV=production
ENV AWS_LWA_ENABLE_COMPRESSION=true
WORKDIR /app
COPY --from=builder /app/package.json ./package.json
COPY --from=builder /app/package-lock.json ./package-lock.json
COPY --from=builder /app/build ./build
COPY --from=builder /app/run.sh ./run.sh
RUN npm ci --omit=dev

CMD exec ./run.sh

lambda-web-adapterREADMEにある通り、以下の命令を記述しています。
あとはRemixアプリケーションの配信に必要なbuildディクトリの配置と、remix-serveに必要なnode_modulesの生成を行っています。

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

cdkプロジェクトの作成

mkdir cdk && cd cdk
cdk init app --language typescript

CDK編集

lib/cdk-stack.tsを編集して以下のコンストラクトを定義します。

  • DockerイメージでのLambda関数を作成
  • Lambda統合のHTTP APIを作成
  • HTTP APIにルートを追加
  • APIエンドポイントを出力
lib/cdk-stack.ts
import * as path from 'node:path'
import * as cdk from 'aws-cdk-lib'
import { HttpApi } from 'aws-cdk-lib/aws-apigatewayv2'
import { HttpLambdaIntegration } from 'aws-cdk-lib/aws-apigatewayv2-integrations'
import {
  Architecture,
  DockerImageCode,
  DockerImageFunction,
} from 'aws-cdk-lib/aws-lambda'
import type { Construct } from 'constructs'

export class CdkStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props)

    const remixFunction = new DockerImageFunction(this, 'RemixFunction', {
      code: DockerImageCode.fromImageAsset(
        path.join(__dirname, '..', '..', 'remix-app')
      ),
      functionName: 'RemixFunction',
      architecture: Architecture.ARM_64,
      memorySize: 256,
    })

    const httpApi = new HttpApi(this, 'HttpApi')
    const integration = new HttpLambdaIntegration(
      'LambdaIntegration',
      remixFunction
    )

    httpApi.addRoutes({
      path: '/{proxy+}',
      integration,
    })

    new cdk.CfnOutput(this, 'ApiEndpoint', { value: httpApi.apiEndpoint })
  }
}

デプロイ

cdk deploy

デプロイ完了後、出力されたURLにアクセスするとRemixのアプリケーションが表示されます。

以下のコマンドで作成されたスタックを削除できます。

cdk destroy

Discussion