Fly(fly.io・fly.dev)

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

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

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


公式・関連サイト


インストール

Installing flyctl | Fly Docs

公式サイトを参照した時に OS に合わせたインストール方法が表示されています。
Windows では PowerShellインストールスクリプトが使われているため、
PowerShell よりコマンドを実行して下さい。

Releases | superfly/flyctl

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


以後コマンドは flyctl で記載していますが、後に fly へ変更される予定です。


アカウント登録

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

flyctl auth signup

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

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

flyctl auth login

アプリの生成

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

flyctl apps create

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

すでに Web 上で生成している場合は代わりに次のコマンドを実行します。

flyctl init

次の対話モードになります。アプリ名・所属に加えて
いくつかのビルダーを選択できるようになり、
Docker イメージを探す事なく、必要なファイルを用意して
すぐにビルドできるようになりました。

? App Name (leave blank to use an auto-generated name) アプリ名を入力

? Select organization: 所属を選択(personal=個人 の項目を含む)

? Select builder:  [Use arrows to move, type to filter](次を選択)
  None
    (Do not set a builder)
  Image
    (Use a public Docker image)
  deno
    Deno builtin
  go
    Go Builtin
  hugo-static
    Hugo static build with web server builtin
  node
    Nodejs builtin
  ruby
    Ruby builtin
  static
    Web server builtin
  staticplus
    Web server builtin
  gcr.io/buildpacks/builder
    GCP Builder for all runtimes
  heroku/buildpacks:18
    heroku-18 base image with buildpacks for Ruby, Java, Node.js, Python,
    Golang, & PHP
  gcr.io/paketo-buildpacks/builder:base
    Small base image with buildpacks for Java, Node.js, Golang, & .NET
    Core
  gcr.io/paketo-buildpacks/builder:full-cf
    Larger base image with buildpacks for Java, Node.js, Golang, .NET
    Core, & PHP
  gcr.io/paketo-buildpacks/builder:tiny
    Tiny base image (bionic build image, distroless run image) with
    buildpacks for Golang
  flyio/builder
    Fly's own Buildpack - currently supporting Deno

hugo-static

Hugo のビルドを実施し、静的 Web サイトを生成します。
config.toml などがあるところに fly.toml も設置し、
hugo server でローカル参照でき、 flyctl deploy でデプロイする状態です。

🎈 Hugo | ふうせん🎈 Fu-sen.

static

staticindex.html などを入れて静的 Web サイトの表示を実現します。

statisplus

staticplus は常時 SSL を実現しますが、
別の実装を予定しているため、後に廃止予定との事です。

静的ファイル共通

これらの静的ファイルでは、次の go 言語による軽量な Web サーバが採用されています。
ただし、ポートは Fly のデフォルトに合わせて 8080 になっています。
なお、Not Found は 404 Not Found の固定表示です。

PierreZ/goStatic | GitHub

heroku/buildpacks:18

Heroku の buildpacks を使用します。
これにより Heroku で運用していた環境を Fly へ移行する事ができます。

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 で使用できます。
もちろん他の言語を使用する場合でも同じ方法が使えます。

その他

Docker イメージのソースを見てもらうのがはやいでしょう。

defaultbuiltins.go - superfly/flyctl | GitHub


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年10月 現在で生成される fly.toml
Select builderNone の場合、次の内容となります。

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

Select builder で他を選択した場合、この情報も含まれます。
例えば hugo-static を選択すると、次が fly.toml に含まれます。

[build]
  builtin = "hugo-static"

2020年10月より、 fly.toml へ環境変数を記載できるようになりました。

[env]
  LOG_LEVEL = "debug"
  RAILS_ENV = "production"
  S3_BUCKET = "balloon-production"

Dockerfile

Docker イメージの構築・実行を入れます。
flyctl の実装により、Dockerfile がなくても容易に使用できるようになりましたが、
Docker を理解している場合は 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 リポジトリを公開しています。


デプロイ

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

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 3 インスタンス常時
micro-2x 0.25 512MB $0.000003 $008 1 インスタンス常時
cpu1mem1 1 コア 1GB $0.000013 $035 8 日分
cpu2mem2 2 コア 2GB $0.000027 $070 4 日分
cpu4mem4 4 コア 4GB $0.000053 $140 2 日分
cpu8mem8 8 コア 8GB $0.000107 $280 1 日分

月 $10 相当は無料の対象なので、(2020 年に入って無料対象金額が減っています)
無料で使用し続けるなら常時稼働は 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 パワーを使用するため一時的に高スペックにして短時間稼働する手段もあります。
作業終了後、スケールの変更またはアプリの削除を忘れないで下さい。

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

なお、 cpu1mem1 以上のスケールアップを行う場合は、普通に使うと課金発生となるため、
通常クレジットカードの登録が必要になります。


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

Regions and Fly | Fly Docs

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

デフォルト状態ではデプロイを行った場所に近いサーバにインスタンスを生成し、
その後、参照の多さに応じてインスタンスを移します。
日本からの場合、東京のサーバ(nrt)が使われるのが理想的ですが、
状況により、香港(hkg)やシンガポール(sin)がメインで使われる場合があります。
また公開している場合はクローラなどの参照により欧米から参照されるため、
参照が少ないうちは欧米のサーバに移される場合があります。
日本の参照が増えると東京などのサーバで参照するようになります。


独自ドメインの設定

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 レコードが表示されます。

なお、Fly では現在ドメインとネームサーバの管理を準備中です。


アプリの一時停止・再開、再起動

意図しない参照を得る事を避けるため、
プロセスを 0 にして参照を一時停止する事ができます。

flyctl suspend

再開は次のコマンドです。

flyctl resume

再起動はデプロイせずにサーバ構成を再構築したい時の使います。

flyctl restart

アプリの削除

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

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 にしている場合、
ビルドの設定を行う( 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 と共に調整して下さい。

またプロジェクトで使用するインスタンス(仮想サーバ)を 1 台だけにしておく事もできます。

flyctl scale set max=1

使用状況を確認する場合はどうすれば良いですか?

Web サイトへログインした状態から右上 Account - Organizations を選択すると
Personal として一人だけ表示されています。この項目を選択し、
左サイドバー Usage を選択すると、転送量、VM の稼働時間・日数を表示します。