2. APIサーバーを設置する
このページでは fly.io に API サーバーを設置する方法を説明します。
2022年9月ごろまで、この解説ページでは fly.io ではなく Heroku を利用する方法を紹介していましたが、2022 年に無料枠が廃止されることが決まった ため、現在は代わりに fly.io を利用する方法を解説しています。
Heroku もしくは他の方法で設置する場合は、こちら をご覧ください。
fly.io とは
fly.io は、クラウド上にサーバーを設置できるサービスです。fly.io には永続的に使える無料枠があり、これを利用することで無料で API サーバーを設置できます。
シェルについて
API サーバーの設置は、CLI から操作する必要があります。macOS ではターミナルなどを用います。Windows にはコマンドプロンプトや PowerShell などがありますが、API サーバーの設置に用いる際は PowerShell のほうを推奨します1。Linux ユーザーの場合はおそらく説明は不要でしょう。
flyctl のインストール
まず、flyctl という fly.io が提供するツールをインストールする必要があります。
macOS
Homebrew がインストールされている場合は、次のコマンドを実行することでインストールできます。
brew install flyctl
インストールされていない場合は、次のコマンドでもインストールできます。
curl -L https://fly.io/install.sh | sh
Linux
次のコマンドを実行することでインストールできます。
curl -L https://fly.io/install.sh | sh
Windows
次のコマンドをPowerShell で実行することでインストールできます。
iwr https://fly.io/install.ps1 -useb | iex
アカウントの作成
fly.io のアカウントを作成していない場合は、次のコマンドを実行してアカウントの作成を行います。
flyctl auth signup
もしすでにアカウントが作成済みの場合は、代わりに次のコマンドを実行することでログインできます。
flyctl auth login
アカウント作成後に下の画像のようにクレジットカードの入力が求められます。クレジットカードを登録することで無料枠が拡張されますが、未登録でも API サーバーを動かすことは可能です。
クレジットカードを登録した場合、念のため、多額の費用がかかっていないか定期的に確認してください。Flocon の作者は、Flocon およびこのサイトの利用により生じた損害等について一切の責任を負いません。
API サーバーのデプロイ
Dockerfile の入手
リリース一覧からダウンロードしたいバージョンを探します。どのバージョンを選ぶべきかよくわからない場合は、基本的には Pre-release が付いてないものの中から最新のバージョンを選べば大丈夫です。
選んだバージョンの下の方にflocon_api_server_flyio.zip
のリンクがあるので、それをダウンロードします。
ダウンロードした zip ファイルを展開します。Dockerfile
というただ 1 つのファイルが展開されたかと思います。管理しやすい場所に空のフォルダを作成し、そのフォルダ内に Dockerfile
ファイルを移動します2。
Dockerfile
の中身は、FROM kizahasi/flocon-api-swap256mb:v*.*.*
(v*.*.*
の部分には API サーバーのバージョンが入ります)の 1 行だけです。ダウンロードせずに自分で作成しても構いません。
kizahasi/flocon-api-swap256mb
イメージの Dockerfile は https://github.com/flocon-trpg/servers/blob/main/docker/api-server-swap256mb/Dockerfile にあります。このリンク先にある Dockerfile を代わりに使用しても問題ありませんが、デプロイする際にビルドなどに少し時間がかかります。
flyctl launch
Dockerfile
のあるフォルダに移動します。フォルダの移動は cd コマンドなどを用います。例えば Dockerfile
が C:/aaa/bbb
にある場合は、cd C:/aaa/bbb
と入力して Enter キーを押すことで移動できます。
移動したら、次のコマンドを実行して、デプロイの下準備を行います。
flyctl launch
Windows で Error name argument or flag must be specified when not running interactively
というメッセージが出る場合は、次のいずれかの方法で回避できます。
- Windows ターミナル をインストールして、Windows ターミナルから PowerShell を起動して実行する。
- WSL を利用する。
App Name (leave blank to use an auto-generated name)
というメッセージが表示されるので好きな App Name を入力します。自動生成でよければ空白でも構いません。
Select region
というメッセージが表示されます。API サーバーをデプロイする地域を設定します。よくわからない場合は、nrt (Tokyo, Japan)
で構いません3。
Would you like to set up a Postgresql database now?
というメッセージが表示されます。データベースとして SQLite を使用する場合はN
を、fly.io の PostgreSQL サービスを使用する場合はy
を入力します。よくわからなければN
を入力してください。
Would you like to deploy now?
というメッセージが表示されます。デプロイの前に行う必要のある設定があるため、ここではN
を入力します。もしy
を選んでデプロイしてしまった場合でも、後から再デプロイできるので問題ありません。
これでflyctl launch
の作業は完了です。Dockerfile
ファイルのある場所に、fly.toml
という fly.io の設定ファイルが作成されていることが確認できます。
永続ストレージの作成
Dockerfile
のあるフォルダで、次のコマンドを実行して永続ストレージを作成します。
flyctl volumes create my_storage --size 1
コマンドのmy_storage
の部分は好きな名前に置き換えても構いません。--size
は1より大きい値にしても構いませんが、よくわからない場合は1を推奨します。
Heroku と異なり、fly.io の永続ストレージにあるファイルは自動的に消去されることはありません。
次に、永続ストレージのマウントに関する設定を行います。fly.toml
ファイルをメモ帳などのテキストエディタで開きます。例えば次のようになっているかと思います。
# fly.toml file generated for flocon-api-tutorial-app on 2022-08-30T00:00:00+09:00
app = "flocon-api-tutorial-app"
kill_signal = "SIGINT"
kill_timeout = 5
processes = []
[env]
[experimental]
allowed_public_ports = []
auto_rollback = true
(以下略)
次の文字列を入力します。my_storage
以外の名前にしている場合は、適宜置き換えてください。入力する場所がわからない場合は、[env]
と[experimental]
の間に入力すれば大丈夫です。
[[mounts]]
source = "my_storage"
destination = "/data"
destination
で指定したパス(上の例では/data
)以外にあるファイルは、再デプロイ時などに自動的に削除されます。このチュートリアルにしたがった設定を行う場合は問題ありませんが、チュートリアルにない設定を行う際はご注意ください。
入力後は下のような感じになっていると思います。
# fly.toml file generated for flocon-api-tutorial-app on 2022-08-30T00:00:00+09:00
app = "flocon-api-tutorial-app"
kill_signal = "SIGINT"
kill_timeout = 5
processes = []
[env]
[[mounts]]
source = "my_storage"
destination = "/data"
[experimental]
allowed_public_ports = []
auto_rollback = true
(以下略)
環境変数の設定
API サーバーの設定をします。設定には環境変数を用います。fly.io では、環境変数のセットは次の 2 つのいずれかの方法で行うことができます。併用することもできます。
fly.toml
に記述するflyctl secrets set
コマンドを利用する
どちらを使っても動作自体に支障はありませんが、fly.io では 慎重に扱うべき値はflyctl secrets set
を使うことを推奨しています。ただし、このチュートリアルで扱う値は、すべてfly.toml
で設定して構いません4。
fly.toml ファイルを用いた設定方法
fly.toml
ファイルを開きます。例えば次のようになっているかと思います。[env]
と[[mounts]]
の間に設定を記述していきます。
最終的な入力例は次のようになります。[env]
と[experimental]
の間の部分以外は編集前と変わっていません。なお、この入力例をそのまま用いるとエラーになりますのでご注意ください(FIREBASE_PROJECT_ID
の部分を変える必要があります)。
# fly.toml file generated for flocon-api-tutorial-app on 2022-08-30T00:00:00+09:00
app = "flocon-api-tutorial-app"
kill_signal = "SIGINT"
kill_timeout = 5
processes = []
[env]
PORT="8080"
AUTO_MIGRATION="true"
FIREBASE_PROJECT_ID="my-firebase-project-id"
DATABASE_URL="file:///data/main.sqlite3"
ENTRY_PASSWORD='{"type":"none"}'
NODE_ENV="production"
[[mounts]]
source = "my_storage"
destination = "/data"
[experimental]
allowed_public_ports = []
auto_rollback = true
(以下略)
fly.toml
ファイルは、TOML という言語で記述します。そのため、.env ファイル(.env.local もこれに含まれます)とは文法が異なりますのでご注意ください。一例として、TOML の場合は=
の右辺が文字列の場合は必ず"
か'
などで囲む必要があります。
PORT, AUTO_MIGRATION
PORT
は"8080"
に、AUTO_MIGRATION
は"true"
に設定します。これらは fly.io にデプロイする全ての API サーバーにおいて共通の設定です。
PORT="8080"
AUTO_MIGRATION="true"
FIREBASE_PROJECT_ID
FIREBASE_PROJECT_ID
は、Firebase の設定情報に書かれています。まずは Firebase の設定情報にアクセスします。
このページの下部に、下のようにconst firebaseConfig = {
で始まるコードがあります。この中からprojectId:
で始まる行を探し、その右の文字列を確認します。下の例ですと"my-firebase-project-id"
が該当します。
const firebaseConfig = {
apiKey: "*************",
authDomain: "*****.firebaseapp.com",
databaseURL: "https://*****.firebaseio.com",
projectId: "my-firebase-project-id",
storageBucket: "*****",
messagingSenderId: "*****",
appId: "************",
measurementId: "*****",
};
この文字列を"
の部分を含めてコピーし、左にFIREBASE_PROJECT_ID=
を付けます。例えば下のようになります。
FIREBASE_PROJECT_ID="my-firebase-project-id"
API サーバー v0.7.10 では FIREBASE_PROJECTID
のみが使用可能でしたが、v0.7.11 以降では代わりに FIREBASE_PROJECT_ID
も使用できます。どちらを用いても同じ挙動となります。
データベース
データベースは下のようにします5。
DATABASE_URL="file:///data/main.sqlite3"
API サーバー v0.7.7 以下では、fly.io などで DATABASE_URL
を使用できません。v0.7.8 以上を使う必要があります。
SQLite の代わりに PostgreSQL もしくは MySQL を使うこともできます。その場合はこちら を参照して設定してください。
ENTRY_PASSWORD
サイトにアクセスする際にパスワードをかけることができます。パスワードは全員に共通ですので、パスワードを設定した場合は何らかの方法で利用者にパスワードをお伝えください。
共通パスワードを設定しない場合は、次のようにします。
ENTRY_PASSWORD='{"type":"none"}'
共通パスワードを設定する場合は、こちら を参照のうえ設定してください。
共通パスワードとは別に、部屋ごとにパスワードをかけることもできます。そのため、共通パスワードを設定しなくても部屋への入室を制限することは可能です。
NODE_ENV
下のようにすることで、API サーバーが本番環境のモードで実行されるようになります。この設定をしなくても動きますが、デバッグ目的などでない限りはproduction
をセットするほうが望ましいです。
NODE_ENV="production"
API サーバーをデプロイする
flyctl deploy
コマンドを実行することでデプロイされます。flyctl launch
コマンドを実行したフォルダと同じフォルダで実行する必要があります。
API サーバーの動作確認
fly.io にアクセスして、右上の「Dashboard」ボタンをクリックします。「Dashboard」ボタンがない場合は、「Sign In」ボタンからログインすると表示されます。
Apps 一覧が表示されるので、デプロイした app を選択します。
Free builder
は自動的に作られるビルド用の app です。そのまま残しておいて構いません。
ページ中央あたりに******.fly.dev
のリンクがあるのでそれをクリックします。
「API サーバーは稼働しています 😊 」のメッセージが表示されればおそらく成功です。エラーメッセージが表示される、もしくは応答がない場合は、デプロイに失敗しています。その場合は******.fly.dev
のリンクがあるページの左上あたりにある「Monitoring」のログを参考にしつつ、設定に誤りがないかどうか確認してください。
API サーバーを再デプロイする方法
fly.toml
やDockerfile
を変更した後、再度flyctl deploy
コマンドを実行することで再デプロイできます。この方法で API サーバーのアップデートもできます。
次のステップに進む
これで API サーバーのセットアップは完了です。次はWeb サーバーを設置するのページをご覧ください。
備考
- Heroku から fly.io への Migration 機能 は Flocon では使えないようです。
- PowerShell を推奨している理由は、flyctl のインストールには PowerShell が必要なのと、コマンドプロンプトでは cd コマンドでドライブをまたぐ場合は
/d
スイッチが必要であり説明が少し複雑になってしまうのを避けるためです。↩ - 空でないフォルダに Dockerfile を置いても構いませんが、Dockerfile のある場所に他のファイルが自動的に作成されるので、Dockerfile 以外にファイルのないフォルダが管理しやすくなります。↩
- 日本からの利用者が多い場合は、物理的な距離が近い
nrt (Tokyo, Japan)
を選ぶことで通信ラグが小さくなるため、わずかですがユーザー体験の向上が期待できます。ただし、fly.io の料金表によると、アメリカにデプロイすると日本と比べてデータ転送の無料枠が大きく料金も安くなるといったメリットがあるため、通信量が多くなると予想される場合はsea (Seattle, Wahington (US))
などといった北米西海岸のリージョンのほうが適しているかもしれません。また、API サーバーは Firebase Authentication によってユーザーの認証を確認するため、Firebase のリージョンも少なからず影響する可能性があります。なお、API サーバーは各ブラウザと通信しますが、Web サーバーとの通信は行いません。そのため、API サーバーは Web サーバーと近い地域にデプロイする必要はありません。↩ ENTRY_PASSWORD
は、パスワードという点を考えると機密情報ですが、ユーザー全員で共有される文字列であることと、部屋ごとに別途パスワードをかけることもできることから、fly.toml
で設定しても大きな問題にはなりにくいと考えられます。もし漏洩が大きな問題になりうるケースの場合は、bcrypt を利用したうえで、flyctl secrets set
コマンドを利用してセットしてください。↩- この例では
/data/main.sqlite3
としていますが、永続ストレージ内にあり、なおかつ他のファイルと重複しない限り、他のパスを指定しても構いません。↩