- はじめに
- Fly.io の Volumes とは
- Fly.io を初期化する
- fly launch 後の状態
- Volume を作成
- Machine と Volume の対を 1 組追加する
- Volume をマウントするために App を設定する
- デプロイする
- PostgreSQL
- Free builder とは
- おわりに
はじめに
Next.js と Rails を使ってオリジナルの Web アプリを開発しています。
当Webアプリには写真保存機能があり、Rails の ActiveStorage を介して外部ストレージに保存する構成にしています。本番環境の外部ストレージをFly.io の Volumes で試してみることにしました。
先に結論から申し上げると、私の開発環境では Fly.io の Volumes は本番環境のストレージとして不向きでした。結果的には外部ストレージは AmazonS3 に乗り換えることになりましたが、Fly.io の Volumes は、まだ日本語の情報も少なく自分と同じくハマる人がいるのではないかと思い、今回試した結果をまとめることにしました。この記事が何らかの形でお役に立てれば幸いです。
以下は、AmazonS3 に乗り換えた記事になります。
Fly.io の Volumes とは
Fly.io が提供している永続的なストレージのことです。
物理サーバー上の NVMe ドライブを分割して提供しているハードウェアで、データベースのファイルを保存したり、設定やセッション、ユーザーデータなどのアプリの状態を保存したり、デプロイや再起動後に持続する必要がある情報を保存したりすることができます。デフォルトのボリュームサイズは 3GB になります。最大サイズは 500GB。分割も可能のようです。
Databases & Storage · Fly Docs
Volumes 利用時に考慮すべき内容
- Volume は、1 つのアプリに紐付く
- Volume は、1 つのリージョンしか指定できない。リージョンの複数指定は不可
- Volume は、1 つの Machine(VM)に紐付ける必要がある。Volume と Machine は 1 対 1 でマッピングが必要
- Volume は、Volume 内で自動的に複製は作られない
- Volume は、ホストする NVMe ドライブが故障すると、アプリのインスタンスがダウンする。アプリの Volume を持つ複数の Machine を実行することでハードウェアの障害を軽減することができる
- Volume は、万が一ドライブが故障した場合はデータが失われてしまう。バックアップ方法は別で検討する必要がある
Volumes 設定時のルール
- 1 つのアプリにつき少なくとも 2 つの Volume の実行が必要
- 1 つの Volume は 1 つの Machine にのみ接続が可能
- そのため、2 つの Volume を準備する場合は、2 つの Machine を用意する必要がある
無料枠
今回は無料枠内で設定を行いました。
- Up to 3 shared-cpu-1x 256mb VMs
- VM は Machine のこと
- 3GB persistent volume storage (total)
- 今回は 1GB を 3 つ用意する
- 160GB outbound data transfer
- outbound data transfer とは、コンピューターネットワークや通信分野において、外部へ転送されるデータ(HTTP 通信)のこと
Fly.io を初期化する
fly launch
済みだったので、途中の設定から進めましたがうまくいかず...。コミュニティに質問を投げたところやり直した方がいいとのことで、初期化してやり直すことにしました。
fly launch
は、Fly.io を立ち上げるコマンドになります。Rails アプリをデプロイする前段階の必要な設定を自動で行ってくれます。
登場人物
- Machine(VM):3 台
- Volume:3 台 × 1GB
- App :Rails API を用意する( App 名:outdoor-heart-sutra-backend)
- DB: PostgreSQL を用意する(DB 名前:outdoor-heart-sutra-backend-db)
Fly.io を初期化しデプロイをやり直す手順
1 . Fly.io のダッシュボードからアプリと DB を削除する
2 . ローカルのDockerfile
とfly.toml
を削除する
3 . fly launch
を実行する。
4 . 新しいDockerfile
とfly.toml
が生成される。
5 . fly deploy
をする
6 . もし You hit a Fly API error with request ID: XXXXXX に遭遇しても慌てない。再びfly deploy
をする。成功するまで何回もやり直す(サーバーが混雑していて一時的に通信できていない可能性が高い)
7 . 上手く行ったらfly open
する。
8 . 設定が反映される。
fly launch 後の状態
fly status
で状態の確認が可能です。
デフォルトで、Machine が 2 台用意されています。fly launch
時に指定したリージョンnrt(東京)
が設定されていることが確認できます。
❯ fly status App Name = outdoor-heart-sutra-backend Owner = personal Hostname = outdoor-heart-sutra-backend.fly.dev Image = outdoor-heart-sutra-backend:deployment-01H2MXM3JKRRCQNPMEESTRGE4D Platform = machines Machines PROCESS ID VERSION REGION STATE CHECKS LAST UPDATED app 148ed5d5a3d668 5 nrt started 2023-06-11T11:05:20Z app 4649xxxxxxxxxxx 5 nrt started 2023-06-11T11:05:20Z
fly volumes list
で Volume の設定状況が確認できます。Volume はまだ設定していないので何も表示されません。
❯ fly volumes list ID STATE NAME SIZE REGION ZONE ENCRYPTED ATTACHED VM CREATED AT
Volume を作成
Volume を作成します。ストレージ名は、英数字、アンダースコアのみ使用可能です。
❯ fly volumes create <ストレージ名> --region <リージョン名> --size <サイズ> - ストレージ名:outdoor_heart_sutra_backend_data - リージョン: nrt(東京) - サイズ: 1GB
警告が表示されますが無視します。
❯ fly volumes create outdoor_heart_sutra_backend_data --region nrt --size 1 Warning! Individual volumes are pinned to individual hosts. You should create two or more volumes per application. You will have downtime if you only create one. Learn more at https://fly.io/docs/reference/volumes/ ? Do you still want to use the volumes feature? Yes ID: vol_lgz1vpp7j7kv78m3 Name: outdoor_heart_sutra_backend_data App: outdoor-heart-sutra-backend Region: nrt Zone: 6082 Size GB: 1 Encrypted: true Created at: 10 Jun 23 08:12 UTC
Volume が 1 台追加できています。
MachineID 148ed5d5a3d668
と VolumeID vol_lgz1vpp7j7kv78m3
のマッピングに成功しています。
❯ fly volumes list ID STATE NAME SIZE REGION ZONE ENCRYPTED ATTACHED VM CREATED AT vol_lgz1vpp7j7kv78m3 created outdoor_heart_sutra_backend_data 1GB nrt e73c true 148ed5d5a3d668 1 day ago
Machine と Volume の対を 1 組追加する
Machine を削除する
先に不要になった Machine を削除します。
Machine 対 Volume のマッピングしたセットをもう一組追加したいのですが、クローン 方式で行うことにします。
まず先にマッピングしていない Machine を削除します。
❯ fly machine destroy <削除したいMachineID> machine <MachineID> was found and is currently in stopped state, attempting to destroy... <MachineID> has been destroyed
Scale the Number of Machines · Fly Docs
クローンする
すでにマッピング済みの MachineID を引数に渡し clone を実行します。
fly machine clone 148ed5d5a3d668 Cloning machine 148ed5d5a3d668 into region nrt Volume 'outdoor_heart_sutra_backend_data' will start empty Provisioning a new machine with image registry.fly.io/outdoor-heart-sutra-backend:deployment-01H2JH5NCPN0X4RV99W0D1WB9N@sha256:c4bb537636be6b041fe026bd04f7bbccc50b2c7c50dd17b08d7c9b7f34d52312... Machine 5683d3d0bd40d8 has been created... Waiting for machine 5683d3d0bd40d8 to start... No health checks found Machine has been successfully cloned!
クローン後の結果
Volume2 台のマッピングが成功しています。
❯ fly volumes list ID STATE NAME SIZE REGION ZONE ENCRYPTED ATTACHED VM CREATED AT vol_3q80vd3wlwkrgzy6 created outdoor_heart_sutra_backend_data 1GB nrt a588 true 5683d3d0bd40d8 1 day ago vol_lgz1vpp7j7kv78m3 created outdoor_heart_sutra_backend_data 1GB nrt e73c true 148ed5d5a3d668 1 day ago
fly status
で確認ができます。Machine が 1 台追加され合計 2 台になっています。
❯ fly status App Name = outdoor-heart-sutra-backend Owner = personal Hostname = outdoor-heart-sutra-backend.fly.dev Image = outdoor-heart-sutra-backend:deployment-01H2QVEXXPGDS97AXPJQC5Q3PQ Platform = machines Machines PROCESS ID VERSION REGION STATE CHECKS LAST UPDATED app 148ed5d5a3d668 11 nrt started 2023-06-12T14:32:13Z app 5683d3d0bd40d8 11 nrt started 2023-06-12T14:33:35Z
Volume をマウントするために App を設定する
新しい Volume をマウントするために設定が必要です。fly.toml
とは、Fly.io アプリケーションの設定ファイルです。Fly.io は、このファイルに従ってデプロイと実行を行います。
Active storage images are not persisting in disk
# backend/fly.toml app = "outdoor-heart-sutra-backend" primary_region = "nrt" console_command = "/rails/bin/rails console" [env] RAILS_STORAGE = "/mnt/volume/storage" [http_service] internal_port = 3000 force_https = true auto_stop_machines = true auto_start_machines = true min_machines_running = 1 [[statics]] guest_path = "/rails/public" url_prefix = "/" [[mounts]] source = "outdoor_heart_sutra_backend_data" destination = "/mnt/volume"
storage.yml ファイルでは、Active Storage がどのようにファイルを保存するかを設定します。
# backend/config/storage.yml local: service: Disk public: true root: <%= ENV.fetch('RAILS_STORAGE', Rails.root.join("storage")) %>
デプロイする
❯ fly deploy
PostgreSQL
fly launch
時に Postgresql をデータベースに設定したので、
以下、自動で生成されます。
名前は App 名の後ろに-db
と付きます。
❯ flyctl status -a outdoor-heart-sutra-backend-db ID STATE ROLE REGION CHECKS IMAGE CREATED UPDATED 5683d3d3ad1338 started primary nrt 3 total, 3 passing flyio/postgres-flex:15.3 (v0.0.42) 2023-06-10T11:28:31Z 2023-06-10T11:28:46Z
Free builder とは
Free builder というアプリは、デプロイ用に自動的に作成されます。
デプロイ時に fly CLI は自動的にアプリを作成し、そのアプリを使用してデプロイビルドを実行してくれます。デプロイをやり直す時に削除しても問題ないようです。万が一削除しても、次にデプロイするときに再び作成されます。
Free builder is created by itself. - Questions / Help - Fly.io
おわりに
これで Fly.io の Volumes の設定は完了です。
しかし、冒頭でも案内した通り、結果として今回は Volumes の導入は断念し Amazon S3 に乗り換えることにしました。
詳細は以下記事にまとめています。