エムスリーテックブログ

エムスリー(m3)のエンジニア・開発メンバーによる技術ブログです

世界最速で Astro SSR を Amplify Hosting で動かしてみた

こんにちは。エムスリーエンジニアリンググループのコンシューマチームでアーキテクトをしている園田です。 本日はコンシューマチームのブログリレー 1 日目です。

2023/11/20 (日本時間だと本日) に AWS の Amplify Hosting で Next.js/Nuxt.js 以外の SSR サポートが発表されました。

aws.amazon.com

aws.amazon.com

さっそく Astro の node アダプターを使った SSR な Web サイトを Amplify Hosting できるかやってみました。

現在公式でサポートされているのは Nuxt のみですが、以下のドキュメントに他の SSR フレームワークにも適用できるようにディレクトリ構成などの仕様が記載されています。

docs.aws.amazon.com

このドキュメントを参考に Astro SSR を構築していきます。 本来であれば Astro の公式アダプターで稼働させるのが正しいのですが、まだアダプターは公開されていないので、自前でこの仕様にフィットさせます。

Astro プロジェクト構築

今回使ったソースは以下のリポジトリにあります。
GitHub - sonodar/amplify-astro-ssr-example

まずは Astro の SSR プロジェクトを node アダプターで構築します。

yarn create astro

続けて node の SSR アダプターをインストールします。

cd amplify-astro-ssr-example/
yarn astro add node

この時点で一旦サーバーを起動してみます。

yarn run dev

ブラウザで http://localhost:4321 にアクセスすると以下が表示されました。

ただ、これだけだと SSR されているのかわかりづらいので SSR 用のページを追加します。

touch src/pages/ssr.astro

以下のようにリクエストの情報を出力するページを作成してみます。

---
import Layout from '../layouts/Layout.astro';
const { method, url } = Astro.request;
const userAgent = Astro.request.headers.get('user-agent');
---
<Layout title="SSR テスト">
    <main>
        <h1>SSR テスト</h1>
        <ul>
            <li>method: {method}</li>
            <li>url: {url}</li>
            <li>userAgent: {userAgent}</li>
        </ul>
    </main>
</Layout>

<style>
    main {
        margin: auto;
        width: 800px;
        color: white;
    }
</style>

この状態で http://localhost:4321/ssr にアクセスしてみます。

良さそうです。

今回は GitHub 連携で Amplify をデプロイするので、あらかじめ GitHub にリポジトリを作成しておきます。 ここまでできたら GitHub に push しておきます。

git push origin main

deploy-manifest.json 作成

公式ドキュメントのとおりに deploy-manifest.json を実装します。

{
  "version": 1,
  "routes": [
    {
      "path": "/_astro/*",
      "target": {
        "kind": "Static",
        "cacheControl": "public, max-age=31536000, immutable"
      }
    },
    {
      "path": "/*.*",
      "target": {
        "kind": "Static"
      },
      "fallback": {
        "kind": "Compute",
        "src": "default"
      }
    },
    {
      "path": "/*",
      "target": {
        "kind": "Compute",
        "src": "default"
      }
    }
  ],
  "computeResources": [
    {
      "name": "default",
      "entrypoint": "entry.mjs",
      "runtime": "nodejs18.x"
    }
  ],
  "framework": {
    "name": "astro",
    "version": "3.5.5"
  }
}

今回は astro@3.5.5 を使ったので $.framework.version3.5.5 にしています。

ビルドスクリプトを実装

Amplify Hosting で動くようにビルドスクリプトを実装します。

touch build-for-amplify-hosting.sh
chmod +x build-for-amplify-hosting.sh

内容としてはビルドした成果物を .amplify-hosting ディレクトリに移動するだけです。

#!/bin/sh

yarn run build

# オプションで port 変更ができない & 環境変数は使えないのでデフォルトポートを上書きする
sed 's|4321|3000|' -i dist/server/entry.mjs

mkdir -p .amplify-hosting/compute

mv dist/client .amplify-hosting/static
mv dist/server .amplify-hosting/compute/default

cp deploy-manifest.json .amplify-hosting/deploy-manifest.json

# 本当は yarn install --production したほうがいい (220MBまで)
cp -r node_modules .amplify-hosting/compute/default/node_modules

ビルドパイプラインを定義

リポジトリのルートに amplify.yml を作成し、ビルドパイプラインを記載します。

version: 1
frontend:
  phases:
    preBuild:
      commands:
        - yarn install
    build:
      commands:
        - bash build-for-amplify-hosting.sh
  artifacts:
    baseDirectory: .amplify-hosting
    files:
      - '**/*'
  cache:
    paths:
      - 'node_modules/**/*'

作成した成果物は GitHub に push しておきます。

echo .amplify-hosting >> .gitignore
git add deploy-manifest.json build-for-amplify-hosting.sh amplify.yml .gitignore
git commit -m "add build scripts"
git push origin main

Amplify Hosting セットアップ

AWS のマネジメントコンソールで Amplify のページを開きます。

まだアプリケーションが 1 つもない場合は以下の Amplify ホスティング「使用を開始する」ボタンを、

すでにいくつかある場合は「新しいアプリケーション」>「ウェブアプリケーションをホスト」を選択します。

GitHub のブランチを選択します。

ビルドの設定では、SSR のログを有効にし、Node.js のバージョンに 20 を指定します。

あとは「保存してデプロイ」を押すとデプロイが開始されます。

この手順だと初回デプロイは失敗します。これは構築のウィザードでビルドイメージを指定していないため Node 20 がインストールできないためです。

ビルドの設定で「構築イメージ」に AmazonLinux2023 を指定します。

ビルドの履歴画面で「このバージョンを再デプロイ」を押して再デプロイします。

今度はデプロイが成功しました。

用意した SSR ページにアクセスしてみると、ちゃんとサーバーサイド処理が実行されていることがわかります。

まとめ

  • Amplify Hosting のディレクトリ構成に合わせたら簡単に Astro SSR をデプロイできた。
  • Astro の公式アダプターがそのうち出ると思うのでそれを使った方がいい。
  • Astro 以外に SveltKit や QwikCity などでも同じやり方でできそう。
  • Amplify Gen2 ってなんだ・・・?

We are hiring

エムスリーでは AWS や GCP といったパブリッククラウドを活用しています。クラウドエンジニアに限らず、フロントエンドやバックエンド、QA エンジニアも随時募集中です。軽く話を聞いてみるだけでも OK ですので、ぜひともカジュアル面談をお申し込みください!

jobs.m3.com

speakerdeck.com