Fly(fly.io・fly.dev)

アプリケーション用プラットフォーム Fly(フライ/fly.io・fly.dev)についてまとめています。

主に Node.js や Go での使用で説明されていますが、
実際には Docker が採用されているため、Docker で動作するものであれば、
多くのプログラミング言語・アプリケーションが動作します。

Fly は細かく仕様変更が行われているようです。
記載内容が後に変更されている可能性がありますので、ご注意下さい。
ここでは 2020年3月 現在の仕様で記載しています。2020年1月 以降この仕様へ移行されています。


公式・関連サイト


インストール

Installing flyctl | Fly Docs

Windows は Curl による flyctl.exe のダウンロードが記載されていますが、
この場合 Curl がインストールされている必要があります。
Web ブラウザから URL 部分をアドレスに入れてダウンロードでも構いません。
flyctl.exe を置いたフォルダに Path を通して下さい。

Releases | superfly/flyctl

GitHub にプロジェクトがあり、こちらからダウンロードも可能です。
Watch」を Releases only にすると更新のメール通知が得られます。


アカウント登録

flyctl から次のコマンドを実行します。

flyctl auth signup

Web ブラウザで表示されます。認証は メールアドレス または GitHub です。
クレジットカード登録はアカウント登録では発生せず、無料枠内での使用となります。

ログインも flyctl からになります。

flyctl auth login

アプリの生成

Dockerfile と公開するアプリのファイルがあるディレクトリに移動しておき、
次のコマンドでアプリの生成を行います。

flyctl apps create

アプリ名は公開時のサブドメインになります。アプリの生成時期でドメイン名が異なり、
2020年3月に作成した場合は https://アプリ名.fly.dev/ が公開アドレスになります。


fly.toml

flyctl apps create でアプリを生成すると、ファイル fly.toml が作られます。

Configuring Fly | Fly Docs

先頭にある app が アプリ名 になっている事を確認して下さい。

app = "アプリ名"

生成された fly.toml ではポート番号 8080 を使用する事になっていますが、
このポート番号は変更できます。

[[services]]
  internal_port = 8080
  protocol = "tcp"

flyctl secrets set PORT=8080 として、環境変数 PORT の設定も可能です。
他サービスで PORT を使用していたアプリを Fly に移行する時に使えます。

その他、参照ポート番号やタイムアウト時間などを設定できます。

Configuration and fly.toml | Fly Docs

Web サイト の Dashboard より Create new app でアプリの作成もできますが、
この場合 fly.toml の生成されないため、作成する必要があります。
2020年3月 現在で生成される fly.toml は次の内容です。

app = "アプリ名"


[[services]]
  internal_port = 8080
  protocol = "tcp"

  [services.concurrency]
    hard_limit = 25
    soft_limit = 20

  [[services.ports]]
    handlers = ["http"]
    port = "80"

  [[services.ports]]
    handlers = ["tls", "http"]
    port = "443"

  [[services.tcp_checks]]
    interval = 10000
    timeout = 2000

Dockerfile

Docker イメージの構築・実行を入れます。

Fly 公式サンプル

superfly | GitHub

GitHub 公式リポジトリにはいくつかプログラミング言語によるサンプルがあります。

リポジトリ superfly/ プログラミング言語
csharp-example C#
go-example Go
rails-example Ruby on Rails
ruby-example Ruby

Apache

httpd | Docker Hub

Docker コミュニティによる Web サーバ Apache の Docker です。
静的 Web サイトが公開できます。
public_html ディレクトリ内に index.html などを入れておきます。

FROM httpd:2.4
COPY ./public_html/ /usr/local/apache2/htdocs/

ポートは 80 になっているので、 fly.toml を変更して下さい。

[[services]]
  internal_port = 80
  protocol = "tcp"

Fly Friday - Flyctl and Ports | Fly Blog
Fly Friday - Customizing with Dockerfiles | Fly Blog

このブログ記事と動画でこの Dockerfile を用いています。

PHP+Apache

php | Docker Hub

Docker コミュニティによる PHP Docker には Apache を追加したイメージがあります。
PHP が動作する Web サイトを公開できます。

FROM php:7.4-apache
COPY ./public_html/ /var/www/html/
RUN sed -i 's/80/8080/g' /etc/apache2/sites-available/000-default.conf /etc/apache2/ports.conf
RUN mv "$PHP_INI_DIR/php.ini-development" "$PHP_INI_DIR/php.ini"

fu-sen/fly-php-apache-example | GitHub

サイト運営者が GitHub リポジトリを公開しています。

Caddy v1+PHP

abiosoft/caddy | Docker Hub
🎈 Caddy | ふうせん🎈 Fu-sen.

Web サーバ Caddy の Version 1 系は公式 Docker がありませんが、
ユーザーによって Docker イメージが公開されています。
この Docker イメージは PHP も使用可能です。

FROM abiosoft/caddy:php
COPY ./public_html/ /srv/
RUN sed -i 's/0\.0\.0\.0/:8080/' /etc/Caddyfile
RUN sed -e '$a tls off' /etc/Caddyfile

fu-sen/fly-caddy1-php-example | GitHub

サイト運営者が GitHub リポジトリを公開しています。

Caddy v2

caddy/caddy | Docker Hub
🎈 Caddy | ふうせん🎈 Fu-sen.

Web サーバ Caddy v2 は公式 Docker があります。
2020年4月、Docker Official Images となりました。
影響で FROM の記載が変わっています。

FROM caddy:alpine
COPY ./public_html/ /usr/share/caddy/

ポートは 80 になっているので、 fly.toml を変更して下さい。

[[services]]
  internal_port = 80
  protocol = "tcp"

fu-sen/fly-caddy2-example | GitHub

サイト運営者が GitHub リポジトリを公開しています。

PHP ビルドイン Web サーバ

ビルトインウェブサーバー | PHP
🎈 PHP ビルトイン Web サーバ

ネット上での一般公開向けにはおすすめできませんが、
PHP ビルトイン Web サーバ での動作も可能です。

FROM php:7.4-alpine
COPY ./ ./
ENV PHP_CLI_SERVER_WORKERS="16"
CMD ["php", "-S", "0.0.0.0:8080"]

fu-sen/fly-php-server-example | GitHub

サイト運営者が GitHub リポジトリを公開しています。

Cloud Native Buildpack

Simpler Fly deployments for NodeJS, Rails, Go, and Java | Fly Blog

Dockerfile を使用する代わりに Cloud Foundry や Heroku などが公開する
Cloud Native Buildpack を指定する方法があります。
Cloud Native Buildpack には Dockerfile があり、
単にローカルの代わりに Cloud Native Buildpack の Dockerfile を参照しているだけです。

Heroku は環境変数 PORT から得ますが、ポート番号は可変します。
Fly では fly.toml に記載しているポート番号(通常 8080)へ変更が必要です。
または flyctl secrets set PORT=8080 として環境変数 PORT の設定が可能です。

fu-sen/fly-php-heroku-example | GitHub

サイト運営者により heroku/buildpacks を用いて環境変数 PORT を設定し
PHP を動作させた簡単な例です。Dockerfile はありません。
これにより Heroku で動作させていた PHP アプリをそのまま Fly で使用できます。
もちろん他の言語を使用する場合でも同じ方法が使えます。


デプロイ

デプロイは次のコマンドです。

flyctl deploy

Docker のデプロイになるので数分要します。完了したら次のコマンドを実行します。

flyctl info

Status = running と表示されていれば正常に公開されています。

標準出力およびエラーログは次のコマンドで表示できます。

flyctl logs

このプロセスはそのまま維持され、リアルタイムで追記されます。


SSL サーバ証明書の発行

サブドメイン アプリ名.fly.dev は通常 SSL サーバ証明書が自動的に発行され、
Fly では比較的最近の環境だと http の参照は https へ転送します。
(http のまま表示させる場合があるため、考慮が必要な場合あり)
SSL での参照でエラーになる場合は、サーバ証明書発行に失敗しています。
次を実行してサーバ証明書を発行して下さい。

flyctl certs create アプリ名.fly.dev

発行は無料の SSL 証明書 Let’s Encrypt ですが、月 $0.10 の料金設定があります。
無料枠の対象です。支払った場合の半額は Let’s Encrypt への寄付となります。

🎈 Let’s Encrypt | ふうせん🎈 Fu-sen.

なお、他の SSL サーバ証明書を使用するようには対応されていません。

Web サイト の Dashboard より アプリ名 を選択した後
左サイドバー Certificates で証明書を表示し、
Add certificate から証明書を発行する事もできます。


仮想マシンの設定(スケール)

Fly App Pricing | Fly Docs

Fly は稼働状況に応じて仮想マシンを変更させます。次があります。
flyctl platform vm-sizes でも参照できます。
2020年3月より、専有プランの種類が増えています。
「月の無料範囲」は仮想マシン以外に課金対象があるため(SSL サーバ証明書・送出の転送量)
使用状況によって、もっと少ない値になります。

種類 CPU RAM 料金(秒) 料金(月) 月の無料範囲
micro-1x 0.12 128MB $0.000001 $002.67 5 インスタンス常時
micro-2x 0.25 512MB $0.000003 $008 1 インスタンス常時
cpu1mem1 1 コア 1GB $0.000013 $035 12 日分
cpu2mem2 2 コア 2GB $0.000027 $070 6 日分
cpu4mem4 4 コア 4GB $0.000053 $140 3 日分
cpu8mem8 8 コア 8GB $0.000107 $280 1.5 日分

月 $15 相当は無料の対象なので、
無料で使用し続けるなら常時稼働は micro-1x または micro-2x が必須です。

現在稼働している稼働マシンは次で確認できます。

flyctl scale vm

デフォルトは micro-2x になっています。
micro-2x は VPS の最小スペック相当です。
静的 Web だったり、単純なレスポンスを返すだけのアプリであれば、
micro-1x で十分に使用できるでしょう。

flyctl scale vm micro-1x

まともにプログラミング言語を用いた稼働になると micro-1x では厳しく、
最低でも micro-2x で稼働させる必要があるでしょう。

flyctl scale vm micro-2x

CPU パワーを使用するため一時的に高スペックにして短時間稼働する手段もあります。
作業終了後、スケールの変更またはアプリの削除を忘れないで下さい。

仮想マシンの変更後はデプロイをしなおします。その間参照を失う事にご注意下さい。


運用する仮想サーバの場所(Region)

Regions and Fly | Fly Docs

Fly は世界各地にサーバを設置しています。
その 1 ヶ所として、日本・東京にもサーバが存在します。
サーバの一覧は flyctl platform regions でも参照できます。

東京のサーバを使用したい場合

日本向けで提供するため、東京のサーバを使用したい場合は、次を実行します。

flyctl scale regions nrt=1

これにより、東京(nrt)に 1 つインスタンスを生成する設定になります。

上のコマンドを実行しなくても、日本から flyctl deploy を行った場合は
通常は東京や近場のサーバでインスタンスが生成されますが、
一般公開した場合は bot の参照などで世界各地から参照を得るので、
それが多くなると、他の地域にインスタンスが移ってしまう場合があります。

世界中から参照を得る場合

デフォルト状態ではデプロイを行った場所に近いサーバにインスタンスを生成し、
その後、参照の多さに応じてインスタンスを移します。

必要な場合、インスタンスを指定する事ができます。
インスタンスの数は料金に影響する事にご注意下さい。

flyctl scale regions 場所=1 場所=1 ...

この設定を解除する場合は次を実行して下さい。

flyctl scale regions --reset-all

独自ドメインの設定

How to do Custom Domains with Fly | Fly Blog

独自ドメインを設定できます。サブドメインも使用可能です。
またサブドメインを * にしたワイルドカードも使用できます。
独自ドメインでの Let’s Encrypt で SSL サーバ証明書が発行されます。
通常 月 $0.10 ですが、ワイルドカードでは 月 $2 になります。
これらは無料枠の対象で、半額は Let’s Encrypt への寄付となります。

🎈 Let’s Encrypt | ふうせん🎈 Fu-sen.

ネームサーバのレコード設定が必要です。

🎈 ネームサーバ | ふうせん🎈 Fu-sen.

CNAME レコードで指定します。

サブドメイン レコード
独自ドメイン CNAME アプリ名.fly.dev

サブドメインなしの場合、CNAME の代わりに ALIAS・ANAME を使用できます。
IP アドレスはデフォルトでは可変するため、A・AAAA レコードでは指定しないで下さい。
(IPv4 アドレスを固定する場合は 月 $18)

独自ドメインでの SSL サーバ証明書発行として、ネームサーバの確認を行います。

flyctl certs create ドメイン名

ワイルドカードの場合は "*.example.net" とドメイン名を "~" で囲んで下さい。

DNS Validation に表示されている CNAME レコードを設定します。

サブドメイン レコード
Hostname 項目 CNAME Target 項目

進行状況は次で表示します。

flyctl certs show ドメイン名

Configured 項目が true となればレコードが正常に設定されています。
Issued 項目に値がある場合も、証明書発行完了です。

Web サイトの Dashboard より アプリ名 を選択し、
左サイドバーの Certificates - Add certificate から追加もできます。
一覧表示から、独自ドメインの View で CNAME レコードが表示されます。


アプリの削除

次のコマンドでアプリを削除できます。

flyctl apps destroy

Web サイトの Dashboard から アプリ名 を選択し、
左サイドバー Settings から Delete App で削除も可能です。


flyctl コマンド

Introducing Flyctl - The Fly CLI | Fly Docs


Q&A

Heroku よりも速いですか?

Turboku - The Art Of Faster Heroku Apps | Fly Blog

こちらのブログ記事では、世界中のベンチマーク平均値が公開されています。

サイト運営者が IP アドレスを返す PHP プログラム
Fly と Heroku で動作させた時は次の結果でした。(2020年3月現在)
(Apache+PHP 7.4。参照する環境変数が異なるので、それぞれ合わせています)
ネームサーバ参照が発生する初回は外し、それから数回参照した平均値です。

プラットフォーム インスタンス 地域 プロトコル レスポンス時間
Fly micro-1x nrt(東京) https 0.06 秒
Heroku Free US(アメリカ) https 0.77 秒(スリープから復旧 9.11 秒)
Heroku Free US(アメリカ) http 0.37 秒(スリープから復旧 7.62 秒)

Heroku では公開向けのアプリとしてアメリカまたは EU の AWS を使用しますが、
(Private Space は日本・東京があります)
Fly は日本から使用した場合、主に東京またはシンガポールのサーバから返します。
スリープがない点でも実用的です。

Google Cloud Run に近いような気がするのですが……

はい。Google Cloud Run と同じように使えます。
最低限、ポート番号を環境変数 PORT にしている場合、
8080 など fly.toml 記載の具体的なポート番号に変更するか、
`` だけで動作するようになります。
環境によっては更に設定が必要かもしれません。

Google Cloud Run と無料枠はどちらかお得ですか?

🎈 簡単に最新版 PHP の Web サーバを使おう。Google Cloud Run で。| ふうせん🎈 Fu-sen.

Google Cloud Run の場合、関係する部分は無料枠が設定されていますが、
Container Registry は無料枠の対象外で、ここで課金が発生します。

Fly App Pricing | Fly Docs

Fly は全て無料枠の対象なので、多大な負荷や参照がない限り完全無料で使用できます。
クレジットカードの登録がなければ無料枠の範囲で使用できるので、その分安全に使用できるでしょう。

Google Cloud Run・Heroku から移行して動作させる方法は?

Google Cloud Run は Dockerfile を使用してコンテナを生成するので、全く同じ仕組みです。
fly.toml 指定のポート番号を入れるか、(デフォルト 8080)
環境変数 PORT を期待する場合 flyctl secrets set PORT=8080 を設定します。

Heroku の場合、Heroku Buildpacks を Fly で使用できます。
flyctl apps create --builder heroku/buildpacks:18 でアプリを生成するか、
fly.toml に次を加えます。

[build]
  builder = "heroku/buildpacks:18"

この fly.toml を Heroku に入れていたプロジェクトのディレクトリに入れて
Heroku では環境変数 PORT を期待するので、 flyctl secrets set PORT=8080
指定のポート番号を入れた上でデプロイして下さい。

GitHub のリポジトリを clone してみましたが、動作しません。

古い日付のリポジトリは動作しない可能性があります。
2018年の公開になっていたり、README のコマンドが fly になっています。

flyctl を実行すると “No app specified” が表示されます。

flyctl は fly.toml から app の値を参照し、そのアプリを対象に実行します。
そのため fly.toml がない場合は "No app specified" になります。
アプリが存在しているディレクトリに移動して実行して下さい。

また、flyctl -a アプリ名 コマンド とする事で、 fly.toml がなくてもコマンドを実行できます。
flyctl --app アプリ名 コマンド に同じです。

fly.io 内を参照した時に “four-oh-four, maybe lost” が表示ができるのですが、何ですか?

four-oh-four = 404 です。http ステータス 404 は Not Found の事です。
ただし、実際には使用できない機能の参照でも表示されています。
正しいリンクをクリックして表示されている場合は下項目を参照して下さい。

公式 Web サイトの Account 内が 404 表示になっています。

Sign Out した後、再度 Sign In すると発生する場合があるようです。
Cookie を削除して Sign In しなおしてみて下さい。

公式 Web サイトの Apps 一覧に作成したアプリが表示されません。

生成したてのアプリは数分経過後に表示されます。
作成した直後のアプリは表示されていませんが、その時でも flyctl での操作は可能です。

急にレスポンスが悪くなりました。

稼働しているサーバ(Regions)が変更されたと思われます。
flyctl status で現在稼働しているサーバの場所を確認してみて下さい。

日本向けであれば、東京や近場のサーバで稼働するようになってきます。
flyctl scale regions nrt=1 として東京サーバを固定させるのも手段です。

世界各地から参照がある場合、比較的参照が多い場所へサーバを移します。
flyctl scale regions では Balance Regionstrue へ変化します。
flyctl をローカルではなく、どこかのサービスを経由する場合は
そのサービスが動作する場所の影響を受ける場合があります。

ネット公開直後だと、bot の参照による影響を受ける可能性があります。
また、Fly サポートを受けた場合も他国から参照になるので、影響があります。

個人利用なので無料で使いたいです。インスタンスが増えるのが嬉しくありません。

fly.tomlservices.concurrency で設定できます。

  [services.concurrency]
    hard_limit = 25
    soft_limit = 20

この場合、20 以上の同時接続が発生すると新たなインスタンスが起動する可能性があり、
25 以上になると確実に新たなインスタンスを起動させます。
この値を大きくすれば、インスタンスの起動がしにくくなります。
当然重い処理で多数参照があるとレスポンスは悪化しますので、
flyctl scale vm と共に調整して下さい。