🐥

MirageXで開発したアプリケーションをFly.ioにデプロイする

2023/12/17に公開

Resonite上で動くリッチなUIを持つアプリケーションを、Reactで開発できるMirageXというフレームワークが登場し、興奮を覚えています。開発者のれにうむさんによる以下の記事をご覧ください。

https://sharedx.notion.site/TypeScript-Resonite-MirageX-5a5dae2e62f9439d9ddf87f6dafd7f51

この記事では、MirageXを使って作成したアプリケーションを、Fly.ioにデプロイする方法を紹介します。

MirageXを使う上での課題

MirageXはとても素晴らしい仕組みである一方で、メインロジックをサーバサイドで実行する関係で、以下の通りのデメリットもあると説明されています。

一方で、デメリットもあります。

  • 完成物を維持するためにインフラコストがかかる。

そこで、Fly.ioにデプロイするようにすれば、無料枠の範囲内でならインフラコストを抑えることができるのではないかと考えました。

ちなみに無料枠の内容は、以下の通りです。

Resources included for free on all plans:

  • Up to 3 shared-cpu-1x 256mb VMs
  • 3GB persistent volume storage (total)
  • 160GB outbound data transfer

Additional resources are billed at the usage-based pricing detailed below.

Fly.io Resource Pricing · Fly Docs

常に使われるようなアプリケーションだとすぐに厳しくなるかもしれませんが、使われていない時は自動的にサーバ(machine)が停止する設定(以下の手順では自動的にそうなります)にすれば、ちょっとしたものであれば無料枠でかなりの程度までいける気もします。

Fly.ioにデプロイする

まず、MirageXはrheniumNV/mirage-x-templateで公開されています。こちらを使って、MirageXのサーバサイドロジックをFly.ioにデプロイしてみます。

Fly.ioへのユーザ登録やflyコマンドのインストール、は済んでいるものとします。初めての方は、Install flyctl · Fly Docsを参考にしてください。

Fly.ioの初期設定をする

MirageXをgit cloneしたディレクトリに移動し、fly launchコマンドを実行します。Fly.io上でのアプリケーションと、ローカルディレクトリ上での設定ファイルの作成が行われます。

$ fly launch
Scanning source code
Detected a NodeJS app
Creating app in /home/kentaro/src/github.com/rheniumNV/mirage-x-template
We're about to launch your NodeJS app on Fly.io. Here's what you're getting:

Organization: Kentaro Kuribayashi    (fly launch defaults to the personal org)
Name:         mirage-x-template      (derived from your directory name)
Region:       Tokyo, Japan           (this is the fastest region for you)
App Machines: shared-cpu-1x, 1GB RAM (most apps need about 1GB of RAM)
Postgres:     <none>                 (not requested)
Redis:        <none>                 (not requested)

? Do you want to tweak these settings before proceeding? (y/N)

アプリの名前だけ変更しておきましょう。最後の質問にyと答えます。ブラウザが開いて設定画面が出てくるので、名前を以下のように変更しました(お好みの名前に変えてください)。

git statusすると、以下の通りファイルが追加されていることがわかります。

$ git status
On branch master
Your branch is up to date with 'origin/master'.

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   package-lock.json
        modified:   package.json

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        .dockerignore
        Dockerfile
        fly.toml

no changes added to commit (use "git add" and/or "git commit -a")

package.jsonへの変更は、@flydotio/dockerfileの追加によるものです。

$ git diff package.json
diff --git a/package.json b/package.json
index 2a410e5..5c0628b 100644
--- a/package.json
+++ b/package.json
@@ -22,6 +22,7 @@
     "prepare": "husky install"
   },
   "devDependencies": {
+    "@flydotio/dockerfile": "^0.4.11",
     "@types/cors": "^2.8.14",
     "@types/express": "^4.17.17",
     "@types/jest": "^29.5.3",

デプロイに関する設定ファイルを編集する

前述の通り.dockerignore, Dockerfile, fly.tomlという3つのファイルが作成されます。ここでは、.dockerignore, Dockerfileを編集します。

.dockerignoreを編集する

.dockerignoreでは、.envファイルを除外する設定になっていますが、ビルド時に.envに書き込んでいる環境変数がないと適切な成果物を得られないので、.envを除外しないようコメントアウトします。

# .env

fly secretsで設定する変数は、サーバの実行時において参照できるものなので、ビルド時には別の形で渡してやる必要があります。以下のドキュメントにあれこれ書かれています。

You can set secrets for your applications, but these are only available at run-time. They aren’t available when building your Docker image without a little extra work.

Build Secrets · Fly Docs

ただ、ここでは特に秘匿情報を扱っているわけではないので、この方法で行くことにしました。もちろん、リポジトリにコミットしてはいけません(.gitignoreでは除外設定がされています)。

Dockerfileを編集する

これも環境変数に関することです。Dockerfile内を、以下の通りコメントアウトします。

# Remove development dependencies
# RUN npm prune --omit=dev

これでサーバの起動するクリプトnpm run startとして設定されている以下のコマンドが適切に実行されるようになります。

"start": "node --require dotenv/config ./dist/server/index.js",

この辺は本来はfly secretsで設定した環境変数を使うのがいいのですが、直前の.dockerignoreの編集で.envがビルド時に参照できるようになっているので、ここでは.envに書かれた環境変数を使うようにしています。

アプリケーションの設定ファイルを編集する

fly statusを実行して、デプロイ先のドメインを確認します。ここではmirage-x-flyio.fly.devというドメインがあてられることがわかります。

$ fly status
App
  Name     = mirage-x-flyio
  Owner    = personal
  Hostname = mirage-x-flyio.fly.dev
  Image    = -
  Platform = machines

.env.sample.envにコピーして、MIRAGE_URLの箇所を上記のドメインを用いたURLに変更します(httpsにするのをお忘れなく)。

MIRAGE_URL="https://mirage-x-flyio.fly.dev/"

Fly.ioにデプロイする

ここまできたら、あとはデプロイするだけです。fly deployコマンドを実行します。

$ fly deploy

(...)

Visit your newly deployed app at https://mirage-x-flyio.fly.dev/

デプロイが完了したら、表示されたURLにアクセスしてつながるかどうかを確かめてみましょう(上記のURLにアクセスすると、記事執筆時現在だとNotFoundと表示されますが、それでOKです)。

クライアントアプリをResonite上で動かす

クライアントアプリは、サーバ上でビルド時に生成されています。サーバ上の/output.brsonから取得できます。今回の例だと https://mirage-x-flyio.fly.dev/output.brson です。

output.brsonというファイルがダウロードされるので、そのファイルをエクスプローラーからResoniteにドラッグ&ドロップします。すると、以下のようにアラートが表示されます。

通信を許可すると、サンプルとして用意されているアプリケーションが表示されます。

おわりに

MirageXで作成したアプリケーションを維持するのにコストがかかる問題について、Fly.ioにデプロイすることで、一定程度解決し得ることを示しました。MirageXは技術的にもめちゃくちゃ面白いので、今度はアプリケーションをつくってみたいとおもいます。

GitHubで編集を提案

Discussion