Herokuの代替としてFly.ioを使ってみた話


- [はじめに](#はじめに)
- [Fly.ioを選んだ理由](#flyioを選んだ理由)
  - [手順](#手順)
    - [その１　flyctlのインストール](#その１flyctlのインストール)
    - [その２　サインアップ & サインイン](#その２サインアップ--サインイン)
    - [その３　アプリをFly上にラウンチ](#その３アプリをfly上にラウンチ)
- [チュートリアルやってみる](#チュートリアルやってみる)
  - [fly.toml 内容](#flytoml-内容)
- [ローカルで動かす方法(22/12/11追記)](#ローカルで動かす方法(22/12/11追記))
- [まとめ](#まとめ)
- [参考文献](#参考文献)

# はじめに
カリルー(仮題)という個人間でのもののシェアの予約・金額計算を行うアプリを開発しようとしています。もうすぐ公開!(進捗90%位？)といったところで、Herokuの無料プランが終了するという連絡がきたので代替を試しがてら、メモとして記事を書いてます。

がっつりHerokuを使ってた人じゃなくて、Webアプリ開発学習中という人向けの内容になります。


作ろうとしていたアプリは、Golangのginテンプレートを使って、フロント・バックともにHerokuにデプロイして実装、DBは1つだけHerokuのものを使用しようと考えてました。

# Fly.ioを選んだ理由
"Heroku 代替"で検索して出た記事をいくつか読みましたが、無料でHerokuばりの機能が搭載されていそうと感じたからです。まず使ってみて合わなければ変えます。

AWSも検討しましたが、APIの作成がGUIで面倒くさそうなのと、12カ月しか無料じゃないほうのプランを使用しなければいけなさそうなのでやめました。

## 手順
公式のガイドに沿って進めていきます。

### その１　flyctlのインストール
flyctlはfly.io用のアプリをローカルで管理するコマンド

Windows PowerShell　で以下のコマンドを入力するだけ。
macで言うbrew、Linuxで言うcurlっぽいです。
```bash:$
iwr https://fly.io/install.ps1 -useb | iex
```

### その２　サインアップ & サインイン
会員登録をします。Githubアカウントでもできるらしいので、せっかくなのでGithubアカウントも作りました。

サインアップ用のコマンドを打つとブラウザが開き、名前とメルアドとパスワードの入力を入力します。なおここからターミナルをGit bashに変えています(PowerShellが嫌いなため)。
```bash:$
flyctl auth signup
```

登録出来たらサインイン
```bash:$
flyctl auth login
```

### その３　アプリをFly上にラウンチ
flyctl launch コマンドでサーバを起動できます。

```
$ flyctl launch

Creating app in C:***********************
Using image flyio/hellofly:latest
? App Name (leave blank to use an auto-generated name): hogehoge
Automatically selected personal organization: ******@gmail.com
? Select region: nrt (Tokyo, Japan)
Error We need your payment information to continue! Add a credit card or buy credit: https://fly.io/dashboard/*****-gmail-com/billing
```

クレジットカードを追加しろと言われた。これはどうやら、Githubと連携してfly.ioにサインアップしたためのようですね。以下がソース。

https://community.fly.io/t/did-trial-plan-end-i-cannot-deploy-apps-anymore-even-with-no-apps/7044

しかたないので、新しいアカウントを作成しなおし、もう一度ログイン、ラウンチしてます。
```
$ fly launch

Creating app in C:*************************:
Scanning source code
Could not find a Dockerfile, nor detect a runtime or framework from source code. Continuing with a blank app.
? App Name (leave blank to use an auto-generated name): hogehoge
Automatically selected personal organization: Flyのユーザ名
? Select region: nrt (Tokyo, Japan)
Created app cariruu in organization personal
Wrote config file fly.toml
```

こんどはうまくいきました。クレジットカードを追加しなくても使えるのは心配事が減ってありがたいですね。

クレジットカードを追加しなければ、1アプリしか作れないようですが、追加すれば3アプリまで無料で作れる(無料使用料を超えると、課金される)などの恩恵があるそうです。とりあえず今回はクレカなしで進めます。


# チュートリアルやってみる
無料で使えそうなことを確認したので、Flyの公式に載っているGoのチュートリアルをやってみます。

https://fly.io/docs/languages-and-frameworks/golang/

サンプルファイルのダウンロード
```
git clone https://github.com/fly-apps/go-example
```

中身は、.gitフォルダを省くとこんな感じ
```
|--go-example
|  |--fly.toml  //設定ファイル。flyctl launchで自動生成
|  |--app.go  // go mainファイル
|  |--go.mod  // goの依存関係ファイル
|  |--go.sum  // goの依存関係ファイル2
|  |--templates
|  |  |--index.html.tmpl // goのテンプレートファイル
```

ブラウザでFlyのHPにアクセスし、上で作ったhogehogeアプリを消してから
```
cd go-example
fly launch
```
すると勝手にGo言語のアプリだと判断してくれて、設定ファイルが作られます。
インプットを求めらる部分は以下のように返答。
```
Scanning source code
Detected a Go app
Using the following build configuration:
        Builder: paketobuildpacks/builder:base
        Buildpacks: gcr.io/paketo-buildpacks/go
? App Name (leave blank to use an auto-generated name): app221023
Automatically selected personal organization: ******
? Select region: nrt (Tokyo, Japan)
Created app app221023 in organization personal
Wrote config file fly.toml
? Would you like to set up a Postgresql database now? No
? Would you like to deploy now? Yes
```
今回はデプロイもまとめてやりました。次回以降以降デプロイする場合は、fly deploy コマンドで行います。

以下のコマンドでアプリオープン。ブラウザに遷移します。
```
flyctl open
```

Goで作ったテンプレートファイルが呼び出されたら成功。

<img width="400" alt="result.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2917913/589bc567-c2a4-43ab-9937-b784bc390649.png">


## fly.toml 内容
勝手に生成されるfly.tomlは以下の内容になっていました。
ビルダーとかDockerがよくわからん。今回はネット上のビルダーと設定を使っているのか。。。。？
```
# fly.toml file generated for app221023 on 2022-10-23T23:16:14+09:00

app = "app221023"
kill_signal = "SIGINT"  //ソフトに送るシャッティングダウン信号
kill_timeout = 5  // タイムアウトの秒数[秒]
processes = []

[build]  // ビルダー　Dockerimageとかのパスを書くらしいです。
  builder = "paketobuildpacks/builder:base"
  buildpacks = ["gcr.io/paketo-buildpacks/go"]

[env]  // 環境変数を設定できる FLY_から始まる名前はダメ
  PORT = "8080"

[experimental]
  allowed_public_ports = []
  auto_rollback = true

[[services]]
  http_checks = []
  internal_port = 8080
  processes = ["app"]
  protocol = "tcp"
  script_checks = []
  [services.concurrency]
    hard_limit = 25
    soft_limit = 20
    type = "connections"

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

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

  [[services.tcp_checks]]
    grace_period = "1s"
    interval = "15s"
    restart_limit = 0
    timeout = "2s"
```

# ローカルで動かす方法(22/12/11追記)
app.goがあるサーバでアプリケーションをビルドする。

```
$ go build
```
生成されたバイナリを実行する。
```
$ bin/app.exe     // windows以外はexeいらない
```
ブラウザで[http://localhost:8080/](http://localhost:8080/)にアクセスすることで、アプリケーションの確認ができる。

ローカルホストでDBを使用する方法については、調べて分かったら追記します。

# まとめ
- Fly.ioでバックエンド～フロントエンドの公開まで無料でクレカの登録なしでできる。初学者向けにちょうどいい
- ただ、Githubでアカウントを作った場合、クレカの登録なしではエラーがでて困る。

# 参考文献
- Heroku 代替まとめ
https://zenn.dev/platina/scraps/a7202c39801445

- Fly.io のGoチュートリアル
https://fly.io/docs/languages-and-frameworks/golang/