はじめに
本記事では、筆者が開発したLaravelアプリを Fly.io を使ってデプロイした際の手順と、実際に遭遇したエラーおよびその対処法を備忘録としてまとめています。
実際のデプロイ作業で詰まったポイントを中心に記載しているため、同じように Fly.io × Laravel × Docker(Sail)構成でデプロイしようとしている方の参考になれば幸いです。
前提条件
開発環境
- フロントエンド:Laravel(Blade), Tailwind CSS, JavaScript, Alpine.js
- バックエンド:PHP / Laravel v12.x
- DB:PostgreSQL
- インフラ:Docker(Laravel Sail)
- OS:Windows 11(WSL2)
デプロイ手順
① Fly.io アカウント作成
以下のURLから Fly.io のアカウントを作成します。
https://fly.io/app/sign-in
筆者は以下の流れで登録しました。
- Googleアカウントで登録
- Gmailにパスワード設定メールが届く
- パスワード設定後の画面で「Add credit card」をクリック
- クレジットカードを登録
補足
Fly.io は従量課金制のためクレジットカード登録が必須です。
ただし現在は 月額 $5 未満であれば請求免除 という運用になっており、
ポートフォリオ用途の小規模アプリであれば無料で運用できるケースもあります。
② flyctl のインストール
flyctl は Fly.io を CLI から操作するための公式ツールです。
VSCode でデプロイ対象のプロジェクトを開き、ターミナル上で以下を実行します。
curl -L https://fly.io/install.sh | sh
注意(Windows + WSL 環境)
筆者は Windows 環境ですが、Docker(Laravel Sail)を使用しているため、
実際の開発環境は WSL 上の Linux です。
そのため Windows用のインストール手順ではなく、Linux用のコマンドを使用する必要があります。
インストール完了後、ターミナルに表示される export 文を .bashrc に追記してパスを通します
# flyctlインストールコマンドの実行結果に以下が表示
export FLYCTL_INSTALL="/home/{ユーザー名}/.fly"
export PATH="$FLYCTL_INSTALL/bin:$PATH"
# これを.bashrcに追記(例:Linux/Ubuntu-24.04/home/{ユーザー名}/.bashrc)
ターミナルで以下を実行し設定を反映させます。
source ~/.bashrc
バージョン確認で動作確認します。
fly -v
③ CLI から Fly.io にログイン
ターミナルで以下を実行します。
fly auth login
# 実行結果
failed opening browser. Copy the url (https://fly.io/app/auth/cli/66346e64733236656e366c61666b6636706c746e6d763367697568376b65756d) into a browser and continue
Opening https://fly.io/app/auth/cli/66346e64733236656e366c61666b6636706c746e6d763367697568376b65756d ...
Waiting for session...⣟
本来ならここでブラウザが自動で開くはずが、WSL 環境(VScodeのリモート接続)ではブラウザが自動起動しなかったため、実行結果のURL をCtrl+クリック。
以下の画面に遷移します。
画面左の「Continue as ~」をクリックすればログイン完了です。
④ 初回デプロイ(Composer エラー)
ターミナルで以下を実行します。
これにより対話形式で自動的にデプロイ設定を行い、最終的にデプロイされます。
fly launch
以下のエラーが発生しました。
Error: Dockerfile doesn't exist and failed to install fly-apps/dockerfile-laravel:
exec: "composer": executable file not found in $PATH
原因
Fly.io の自動セットアップ処理中 composer が必要になりますが、
WSL 側に Composer がインストールされていなかったためです。
開発環境ではDockerコンテナ内にcomposerがあり動作していた。
対処
WSL に Composer をインストールします。
ターミナルで以下の順に実行します。
# パッケージリストの更新
sudo apt update
# PHPと必要な拡張、unzipのインストール
sudo apt install php-cli php-mbstring unzip curl -y
# composerのインストール
curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer
バージョン確認で動作を確認します。
composer -v
⑤ PHP 拡張機能エラー
再度 fly launch を実行すると、次は以下のエラーが発生。
Installation failed, reverting ./composer.json and ./composer.lock
原因
先ほどインストールしたPHP に xml や dom の拡張機能が不足しており、Composer が Laravel の依存関係を解決できなかったため。
対処
必要な拡張機能をインストールします。
ターミナルで以下を実行します。
# パッケージリストの更新
sudo apt update
# 拡張機能のインストール
sudo apt install php8.3-xml php8.3-curl php8.3-zip -y
⑥ 初回デプロイ完了
中途半端に作成されたアプリを一度削除します。
ターミナルで以下を実行します。
fly apps destroy {アプリ名}
再度デプロイします。
ターミナルで以下を実行します。
fly launch
処理が進み、「このアプリに fly.tomlの設定を使いますか?」とのメッセージが表示されます。
これは前回のfly launchでfly.toml(デプロイ設定ファイル)が作られているため、表示されるメッセージです。
y(Yes)と入力しenterで確定します。
? Would you like to use this fly.toml configuration for this app? (y/N)
処理が進み、次に以下の2つが表示されます。
# デフォルトのデプロイ設定
1 We're about to launch your Laravel app on Fly.io. Here's what you're getting:
2
3 Organization: USER (fly launch defaults to the personal org)
4 Name: test-app (from your fly.toml)
5 Region: Tokyo, Japan (from your fly.toml)
6 App Machines: shared-cpu-1x, 256MB RAM (from your fly.toml)
7 Postgres: "test-app-db", Basic plan ($38/mo), region nrt (determined from app source)
8 Redis: Pay-as-you-go Plan: 10 GB Max Data Size, eviction disabled (determined from app source)
9 Tigris: <none> (not requested)
# 「設定を変更しますか?」のメッセージ
? Do you want to tweak these settings before proceeding? (y/N)
設定を変更するのでyと入力しenterで確定します。
重要
デフォルトのデプロイ設定ではManaged Postgresが自動提案されます!
これはFly.ioのDB管理サービスで、何もしなくても月額$38.00(¥6,000弱)の料金がかかってしまいます。
以前は開発用オプション(従量料金)がデフォルトでしたが、現在Fly.ioではこの設定から開発用オプションは選択できないようになっているので、ここでは一旦DBの立ち上げはしないよう設定を変更して進めていきます。
従来の従量課金のDBを立ち上げる方法は後ほど解説します。
処理が進み、以下のメッセージが表示されます。
failed opening browser. Copy the url (https://fly.io/cli/launch/47328648236...) into a browser and continue
Waiting for launch data...⣷
ここでも同様にブラウザが自動で開かないので、実行結果のURL をCtrl+クリック。
デプロイ設定画面に遷移するのでPostgresという項目のProviderをManaged Postgresからnoneに変更し、最下層のConfirm Settingsボタンで設定を確定します。
ターミナルに戻ると、処理が進み「fly.tomlを上書きしますか?」と表示されます。
yと入力しenterで確定します。
? Overwrite "/home/{ユーザー名}/{ファイル名}/.github/workflows/fly-deploy.yml"? (y/N)
以下のようにメッセージと、アプリのURLが表示されたら初回デプロイ完了です。
🎉 SUCCESS! Your app is live and ready to use! 🎉
Visit: https://test-app.fly.dev/
⑦ CSS / JS が当たらない問題(Mixed Content)
デプロイしたアプリにスタイルが当たっておらず、ブラウザの開発者ツールを見ると以下のエラーが表示されていた。
Mixed Content: The page at ... was loaded over HTTPS, but requested an insecure resource
原因
Laravel がアセットの URL を http で生成おり、Fly.ioなどのクラウドサービスではブラウザ・サーバー間をhttpsで通信するので、httpのアセットファイルはブラウザでブロックされいたため。
対処
AppServiceProvider.php の bootメソッド に以下を追加します。
use Illuminate\Support\Facades\URL;
public function boot()
{
// 本番環境ではURLをhttpsで書き出し
if (config('app.env') === 'production') {
URL::forceScheme('https');
}
}
ターミナルで以下のコマンドを実行します。
これによりデプロイしたアプリを更新し、設定を反映します。
fly deploy
⑧ DB 構築(Legacy Postgres)
以前のような開発用DBを立ち上げる方法を模索していたところ、Fly.ioのDashboardのサイドバーに Legacy Postgres という怪しいものを発見しました。
開くとDocumentへのリンクがあり、そこにDBの立ち上げ〜設定について記載があったので、これを使用します。
参照:Fly Postgres
fly.toml の [env] にDB構築用の環境変数を追加します。
[env]
# .envファイルより`DB_~`をコピペ
DB_CONNECTION = 'pgsql'
DB_HOST = 'pgsql'
DB_DATABASE = 'laravel'
DB_PASSWORD = 'password'
DB_PORT = '5432'
DB_USERNAME = 'sail'
ターミナルで以下のコマンドを実行し、設定を反映します。
fly deploy
ターミナルで以下のコマンドを実行し、DBクラスターを作成します。
fly postgres create
処理が進みDB名を求められるので入力して enter で確定します。
? Choose an app name (leave blank to generate one): # ここにDB名を入力
処理が進み、リージョン(地域)選択を求められるので、↓ で Tokyo, Japan (nrt) を選択して enter で確定します。
? Select region: [Use arrows to move, type to filter]
Paris, France (cdg)
Dallas, Texas (US) (dfw)
Secaucus, NJ (US) (ewr)
Frankfurt, Germany (fra)
Sao Paulo, Brazil (gru)
Ashburn, Virginia (US) (iad)
Johannesburg, South Africa (jnb)
Los Angeles, California (US) (lax)
London, United Kingdom (lhr)
> Tokyo, Japan (nrt)
Chicago, Illinois (US) (ord)
Singapore, Singapore (sin)
San Jose, California (US) (sjc)
Sydney, Australia (syd)
Toronto, Canada (yyz)
処理が進み、プラン選択を求めまれます。
? Select configuration: [Use arrows to move, type to filter]
> Development - Single node, 1x shared CPU, 256MB RAM, 1GB disk
Production (High Availability) - 3 nodes, 2x shared CPUs, 4GB RAM, 40GB disk
Production (High Availability) - 3 nodes, 4x shared CPUs, 8GB RAM, 80GB disk
Specify custom configuration
処理が進み、「1時間アクセスがなかったら、サーバーを自動的に一時停止(スリープ)させますか?」と聞かれるので、N と入力して enter で確定します。
ここで
yを選択すると、リソースの節約(従量料金の節約)になりますが、小規模なプロジェクトだとNでも$5未満に収まるので、筆者はNとしました。
? Scale single node pg to zero after one hour? (y/N)
これにて処理が進み、DB構築が完了します。
Fly.ioの Apps と Legacy Postgres に、作成したDBが表示されているか確認します。
ターミナルにて以下のコマンドを実行し、デプロイしたアプリにDBをアタッチ(接続)します。
fly postgres attach {DB名} --app {アプリ名}
ターミナルで以下のコマンドを実行し、設定を反映します。
fly deploy
続いて、環境変数の一部修正を行います。
先ほどの attachコマンド でFly.ioの環境変数に DATABASE_URL がセットされていますが、 Laravel v12.x ではデータベースの環境変数名を DB_~ で参照するため、現状のままではエラーとなってしまいます。
-
Fly.ioを開き、Dashboardの
Appsよりデプロイしたアプリをクリック -
Overviewに遷移するので、サイドバーよりSecretsをクリック -
いくつかの環境変数が設定されており、その中にある
DATABASE_URLを削除 -
デプロイしたアプリを開いた状態で、ターミナルで以下を実行
bash# 以下のコマンドでFly.ioの仮想マシンに入る fly ssh console # 以下のコマンドでDBのURLを参照する echo $DATABASE_URL; -
出力結果のURLをコピーしておく
-
Fly.ioの
Secretsに戻りAdd Secretsをクリック -
NameをDB_URL、Secretsに先ほどコピーしたURLを貼り付けてSet Secretをクリック
これにより環境変数がきちんと参照されます。
ターミナルで以下のコマンドを実行し、設定を反映します。
fly deploy
これにてアプリとDBの接続が完了しました。
ターミナルで以下を実行し、接続を確認します。
# 以下を実行する
fly postgres users list --app {DB name}
# 以下のようにアプリの情報が表示されたらOK
NAME SUPERUSER DATABASES
{アプリ名} yes {アプリ名}, postgres, repmgr
flypgadmin yes {アプリ名}, postgres, repmgr
postgres yes {アプリ名}, postgres, repmgr
repmgr yes {アプリ名}, postgres, repmgr
⑨ DB 接続エラー
アプリでユーザー登録をしようとしたところ レスポンスコード500サーバーエラー が表示され、Fly.ioの Apps → Logs & Errors の、Live Machine Logsに以下のエラーメッセージが表示されていました。
{"message":"SQLSTATE[08006] [7] could not translate host name \"pgsql\" to.........
ターミナルで以下を実行し、DBの情報を確認したところ host の値が pgsql となっていました。
# 以下のコマンドでFly.ioの仮想マシンに入る
fly ssh console
# 以下のコマンドでDBの設定情報を確認
php artisan config:show database
原因
DB構築の初め .env からコピペした環境変数に DB_HOST = 'pgsql' が含まれていたが、これは Laravel Sail 開発用の設定で、本番環境では存在しないため。
[env]
DB_CONNECTION = 'pgsql'
DB_HOST = 'pgsql' # これが原因
DB_DATABASE = 'laravel'
DB_PASSWORD = 'password'
DB_PORT = '5432'
DB_USERNAME = 'sail'
対処
fly.toml から DB_HOST を削除して再デプロイ。
fly deploy
⑩ マイグレーション未実行エラー
再度ユーザー登録を試みたが再びエラーとなり、fly.ioのログに以下が表示されました。
{"message":"SQLSTATE[42P01]: Undefined table: 7 ERROR: relation ......
原因
マイグレーションが未実行で、構築したDBにテーブルが無かったため。
対処
fly.toml に以下を追加。
これにより fly deploy の際に、マイグレーションも実行されます。
[deploy]
release_command = "php artisan migrate --force"
ターミナルで以下を実行し、マイグレーションも実行します。
fly deploy
最後に
非常に長い記事になりましたが、同じ構成で Fly.io にデプロイする方の助けになれば幸いです。
実際に詰まったポイントをすべて記載しているため、エラー対応の参考として活用していただければと思います。


