Remixが流行ってそうなので、AWS Amplify Hostingにデプロイしてみる
はじめに
こんにちは!
犬専用の音楽アプリ オトとりっぷでエンジニアしています、足立です!
この記事では、Remix を AWS Amplify Hosting するための方法を解説しています。
「とりあえず結果だけくれ!」という方は、こちらにレポジトリを公開しておりますので、よろしければご覧ください。
目次
- 背景
- Remix が流行ってる?
- Amplify Hosting で SSR
- 手順
- Remix Init
- Amplify Setting
- Deploy
- 追加修正
背景
Remix が流行ってる?
どうやら、Remix が流行る兆しがあるみたいです!
状況については、こちらの記事が非常にわかりやすいです。
私は主に Next.js を利用しているので、Remix は初めてです。
せっかくなので流れに乗って Remix を調査してみよう、というのがこの記事の主旨です。
Amplify Hosting で SSR
Amplify Hosting で SSR 可能なフレームワークは、以前は Next.js のみ提供でしたが、昨年の 11 月に他のフレームワークでもようやく利用可能になりました。
Astro や Hono などのフレームワークについて、先人達が貴重な情報を残してくださっています。
そんな中、「よーし!Remix が流行ってそうなので、Amplify にもデプロイしてみるか!」と思ったら Remix に関する情報がどこにも出てなかったのでまとめてみました。
Remix に慣れていないので、間違いなどありましたらご指摘いただけると幸いです。
手順
Remix Init
まずは Remix をQuick Start (5m)で Init していきます。
Github 連携のために、すべての工程の前に空のレポジトリを作成しておいてください。
$ cd <root>
$ npm init -y
$ npm i @remix-run/node @remix-run/react @remix-run/serve isbot@4 react react-dom
$ npm i -D @remix-run/dev vite
次に vite の設定ファイルを作成します。
$ touch vite.config.js
import { vitePlugin as remix } from "@remix-run/dev";
import { defineConfig } from "vite";
export default defineConfig({
plugins: [remix()],
});
次にエントリーファイルを作成します。
$ mkdir app
$ touch app/root.jsx
import { Links, Meta, Outlet, Scripts } from '@remix-run/react';
export default function App() {
return (
<html>
<head>
<link rel='icon' href='data:image/x-icon;base64,AA' />
<Meta />
<Links />
</head>
<body>
<h1>Hello world!</h1>
<Outlet />
<Scripts />
</body>
</html>
);
}
それではローカルでビルドしてスタートさせてみます。
remix-serve を動かすためにはpackage.json
の一部書き換えが必要です。
{
"type": "module"
// ...
}
$ npx remix vite:build
$ npx remix-serve build/server/index.js
http://localhost:3000 にアクセスして Hello world!
と表示されていれば成功です。
次にサーバ上で動かすための設定を追加していきます。
Quick Start では Express を使った例が出ているので、それに従います。
$ npm i express @remix-run/express cross-env
$ touch server.js
import { createRequestHandler } from '@remix-run/express';
import express from 'express';
// notice that the result of `remix vite:build` is "just a module"
import * as build from './build/server/index.js';
const app = express();
app.use(express.static('build/client'));
// and your app is "just a request handler"
app.all('*', createRequestHandler({ build }));
app.listen(3000, () => {
console.log('App listening on http://localhost:3000');
});
では、サーバにアクセスしてみます。
$ node server.js
こちらでもデカデカとHello world!
と表示されていれば成功です。
Amplify Setting
次に Amplify Hosting 用のセッティングを追加していきます。
Express サーバを Amplify にデプロイするための公式ドキュメントはこちらです。
これに従って、各種設定を追加していきます。
まず、「Amplify deployment manifest」なるものを作成します。
$ touch deploy-manifest.json
{
"version": 1,
"framework": { "name": "express", "version": "4.18.2" },
"imageSettings": {
"sizes": [
100,
200,
1920
],
"domains": [],
"remotePatterns": [],
"formats": [],
"minimumCacheTTL": 60,
"dangerouslyAllowSVG": false
},
"routes": [
{
"path": "/_amplify/image",
"target": {
"kind": "ImageOptimization",
"cacheControl": "public, max-age=3600, immutable"
}
},
{
"path": "/*.*",
"target": {
"kind": "Static",
"cacheControl": "public, max-age=2"
},
"fallback": {
"kind": "Compute",
"src": "default"
}
},
{
"path": "/*",
"target": {
"kind": "Compute",
"src": "default"
}
}
],
"computeResources": [
{
"name": "default",
"runtime": "nodejs18.x",
- "entrypoint": "index.js"
+ "entrypoint": "server.js"
}
]
}
公式ドキュメントからのコピペですが、一点だけエントリーファイルを変更しています。
次に「post-build script」なるものを追加します。
こちらはビルド後に必要なファイルを必要な場所に配置するためのスクリプトっぽいです。
$ mkdir bin
$ touch bin/postbuild.sh
#!/bin/bash
rm -rf ./.amplify-hosting
mkdir -p ./.amplify-hosting/compute/default
cp -r ./build ./.amplify-hosting/compute/default/build
cp -r server.js ./.amplify-hosting/compute/default
cp -r ./node_modules ./.amplify-hosting/compute/default/node_modules
cp -r public ./.amplify-hosting/static
cp deploy-manifest.json ./.amplify-hosting/deploy-manifest.json
こちらも、ほとんど公式からのコピペですが、ビルド済みファイルの命名を変更し、server.js をコピーに含めるように修正しました。
このままでは public が存在しないと怒られるので、適当に Icon を追加しておきます。
$ mkdir public
最後にpackage.json
を修正し、ビルド後に postbuild.sh が適応されるように修正します。
{
...
"scripts": {
"build": "remix vite:build",
"dev": "remix vite:dev",
"start": "remix-serve ./build/server/index.js",
"postbuild": "chmod +x bin/postbuild.sh && ./bin/postbuild.sh"
},
...
}
ビルドして、.amplify-hosting
以下に必要なファイルが移動されていれば成功です。
$ npm run build
Deploy
デプロイしていきましょう。
詳細は、先達とほとんど同じなので、割愛します。
気を付けるポイントとしては、amplify.yml
を以下の通りに設定してください。
version: 1
frontend:
phases:
preBuild:
commands:
- npm install
build:
commands:
- npm run build
artifacts:
baseDirectory: .amplify-hosting
files:
- '**/*'
デプロイ完了したら、https://main.<ID>.amplifyapp.com にアクセスしてみましょう!
きっと、このページは動作していません
とエラーページが返ってきます。あれ?
追加修正
原因を探っていきます。
AWS Amplify Hosting のマネージメントコンソール画面の左側サイドバーからモニタリング
をクリックし、メイン画面の上部タブの中からホスティングしているコンピューティングログ
をクリックし、該当ブランチのCloudWatch ログストリーム
をクリックします。
そうすると、CloudWatch でサーバサイドのログが見れるので、何のエラーが発生してるのか確認します。
INIT_REPORT Init Duration: 192.25 ms Phase: init Status: error Error Type: Runtime.ExitError
LOGS Name: bootstrap State: Already subscribed Types: [Platform, Function]
(node:18) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
(Use `node --trace-warnings ...` to show where the warning was created)
/var/task/server.js:1
import { createRequestHandler } from '@remix-run/express';
^^^^^^
SyntaxError: Cannot use import statement outside a module
...
どうやら、@remix-run/express
が読み込めずエラーで落ちているみたいです。
こちらの指示通り、package.json に"type": "module"
を追加します。
$ touch bin/package.json
{
"type": "module"
}
#!/bin/bash
rm -rf ./.amplify-hosting
mkdir -p ./.amplify-hosting/compute/default
cp -r ./build ./.amplify-hosting/compute/default/build
cp -r server.js ./.amplify-hosting/compute/default
+ cp -r bin/package.json ./.amplify-hosting/compute/default
cp -r ./node_modules ./.amplify-hosting/compute/default/node_modules
cp -r public ./.amplify-hosting/static
cp deploy-manifest.json ./.amplify-hosting/deploy-manifest.json
追加の修正を Github に Push して、再度デプロイしてみます。
次はデカデカとHello world!
が無事に表示されましたでしょうか?
最後に
いかがでしたでしょうか。
これはあくまで SSR できたよっていうことなので、サーバサイドでデータフェッチをするなど、もう少し深い利用シーンのやり方についても引き続き調査してみたいと思います。
また、Remix の方もリ
の字ぐらいしか味わってないので、もっと触りたいですね。
もし犬専用の音楽アプリに興味を持っていただけたら、ぜひダウンロードしてみてください!
Discussion