サイトアイコン

toLog

Remix を Lambda で動かしたい

  • 更新日:
  • 投稿日:

この記事は最終更新日から半年以上が経過しています。

はじめに

Remix を検証がてら実機でお手軽に動かしたいと思い Lambda で動かしてみました。

なぜ Lambda か?

(1) 筆者が慣れていること、
(2) (使いようによっては)お財布に優しこと、
(3) お手軽にデプロイできること、
などが理由です 😅

今回は aws-lambda-web-adapter を用いて Remix を起動するプロジェクトを備忘します。

サンプルリポジトリも用意しているので、必要に応じてご参照ください。

内容

前述の通り、今回は aws-lambda-web-adapter で Remix の WEB アプリを起動します。
と言いつつ、実態としては同ツールの nextjs-zip のサンプルを大いに参考に、それを Remix に転用している程度です。

ざっと今回のプロジェクトの特徴は次になります。

  • Remix 側のアプリケーションは init 時から変更はなし
  • API Gateway の HTTP API でサクッとエンドポイントを構成
  • Makefile で install、build、artifiacts 等の一連のデプロイ処理を集約操作

次にざっと主要なファイルについて紹介します。

(SAM) template.yml

プロビジョニング用の SAM テンプレートです。
ほぼほぼ aws-lambda-web-adapter のサンプルを転用していますが ArchitecturesLayers は、arm64 に変えています。

1AWSTemplateFormatVersion: "2010-09-09"
2Transform: AWS::Serverless-2016-10-31
3Description: >
4  serverless-remix-demo
5
6  Sample SAM Template for serverless-remix-demo
7
8Globals:
9  Function:
10    Timeout: 10
11
12Resources:
13  RemixFunction:
14    Type: AWS::Serverless::Function
15    Properties:
16      CodeUri: ./
17      MemorySize: 256
18      Handler: run.sh
19      Runtime: nodejs20.x
20      Architectures:
21        # - x86_64
22        - arm64 # ここはお使いの環境に合わせてください
23      Environment:
24        Variables:
25          AWS_LAMBDA_EXEC_WRAPPER: /opt/bootstrap
26          AWS_LWA_ENABLE_COMPRESSION: true
27          RUST_LOG: info
28          PORT: 8000
29      Layers:
30        # - !Sub arn:aws:lambda:${AWS::Region}:753240598075:layer:LambdaAdapterLayerX86:20
31        - !Sub arn:aws:lambda:${AWS::Region}:753240598075:layer:LambdaAdapterLayerArm64:20
32      Events:
33        RootEvent:
34          Type: HttpApi
35          Properties:
36            Path: /
37            Method: any
38        ProxyEvent:
39          Type: HttpApi
40          Properties:
41            Path: /{proxy+}
42            Method: any
43    Metadata:
44      BuildMethod: makefile
45
46Outputs:
47  RemixFunctionURL:
48    Description: "API Gateway endpoint URL for Remix"
49    Value: !Sub "https://${ServerlessHttpApi}.execute-api.${AWS::Region}.${AWS::URLSuffix}/"

Makefile

ビルドして、必要なファイルを zip 化しています。
ファイル構成は、公式の indie-stack と呼ばれるテンプレートの Dockerfile を参考にしています。

1BUILD_DIR=${PWD}
2
3install:
4	rm -rf node_modules
5	npm ci
6
7build:
8	npm run build
9
10artifacts:
11	# Production packages installed
12	npm ci --omit=dev
13
14	cp package.json $(ARTIFACTS_DIR)
15	cp -r node_modules/. $(ARTIFACTS_DIR)/node_modules
16	cp -r build/. $(ARTIFACTS_DIR)/build
17	cp -r public/. ${ARTIFACTS_DIR}/public
18	cp run.sh $(ARTIFACTS_DIR)
19
20	cd $(ARTIFACTS_DIR) && zip -ry ${BUILD_DIR}/lambdaFunctionSrc.zip .
21	rm -rf "$(ARTIFACTS_DIR)"
22	mv ${BUILD_DIR}/lambdaFunctionSrc.zip "$(ARTIFACTS_DIR)"
23
24build-RemixFunction: install build artifacts

run.sh

純正の remix-serve と言う node サーバーで起動しています。

1#!/bin/bash
2
3HOSTNAME=0.0.0.0 exec ./node_modules/.bin/remix-serve ./build/index.js

デプロイ

あとは、SAM CLI でデプロイするだけです。

1sam build
2sam deploy --guided

余談

定番の API Gateway の Rest API 構成もあるのですが、今回は手軽に起動することを目的としたため外しています。

と言うのも、Rest API ではエンドポイントにステージ名が含まれるため、Remix 側が想定しているパスと API Gateway 側のパスが異なり、静的ファイルのリクエストエラーが起きる問題に遭遇しました。

1# パスずれの例
2
3# API Gateway のエンドポイント
4https://xxx.execute-api.ap-northeast-1.amazonaws.com/prod/hoge.js
5
6# Remix の想定しているパス
7https://xxx.execute-api.ap-northeast-1.amazonaws.com/hoge.js

これを回避するためには、Custom Domain を使うか、Remix 側で basename を指定するなどが考えられます。
これを Rest API 側で回避できる設定などあるのでしょうか? 🤔

おわりに

キャッシュ周りも取り回したいとなったら CloudFront と組み合わせると、より快適な UX が提供できそうです。
と言いつつ、そこまで体力はなく今回はここまで...と言うかよく分かっていない 😅


プロフィール画像

canji

とにかく私的にサービスを作りたい発作を起こしている。お腹はペコペコ。

  • toLog Tools icon
  • dots icon