3.fly deployでrequires php >=8.4.1と出る
fly deployの途中でrequires php >=8.4.1と出て止まった場合は、fly.tomlのPHP_VERSIONが'8.2'のままです。
R2を使うためにleague/flysystem-aws-s3-v3を入れたとき、手元のPHPが8.4以上だと、一緒にPHP 8.4以上でないと動かないsymfony/filesystemのバージョンが入ります。
fly launchが作ったfly.tomlは8.2になっているので、'8.4'に変えてから、もう一度fly deployしてください。
[build]
[build.args]
NODE_VERSION = '22'
PHP_VERSION = '8.4'
4.公開したLaravelアプリのデザインが崩れる
ページは表示されるのに、デザインが全部崩れている場合は、CSSの読み込みがブロックされています。
Fly.ioは、ブラウザからのhttpsのアクセスをいったん受け取り、Laravelにはhttpとして渡します。
そのためLaravelは自分がhttpで開かれていると判断し、CSSやJavaScriptのURLをhttp://で書き出します。
httpsのページの中にhttpのファイルが混ざると、ブラウザは安全でないと判断して読み込みをブロックします(mixed content)。
直し方は、bootstrap/app.phpにtrustProxiesの1行を入れて、もう一度fly deployすることです。
->withMiddleware(function (Middleware $middleware): void {
$middleware->trustProxies(at: '*');
})
trustProxiesは、Fly.ioから届いた「元はhttpsだった」という情報を信じてよいとLaravelに伝える設定です。
これでURLがhttps://で出力されます。
5.Laravelアプリが500エラーになる・Neonのデータベースにつながらない
fly logsにデータベース関連のエラーが出ていたら、次の3つを確認します。
fly secrets listにDB_CONNECTIONとDB_URLがあるか- 貼ったNeonの接続文字列が、
postgresql://から最後まで欠けずに入っているか - 接続文字列のホスト名に
-poolerが付いていないか
fly secretsは、パスワードなどの秘密の値を環境変数としてFly.ioに登録する仕組みで、ローカルの.envの本番版にあたります。
どれかが違っていたら、もう一度fly secrets setを実行すれば値が上書きされます。
fly secrets set DB_CONNECTION=pgsql DB_URL="<Neonの接続文字列>"
1つ目は、DB_CONNECTION=pgsqlを忘れると、LaravelがSQLiteを使おうとするためです。
また、変数名はDB_URLです。
古い記事ではDATABASE_URLと書かれていることがありますが、Laravel 11以降はDB_URLを使います。
3つ目は、Neonの「Connect」画面で「Connection pooling」(たくさんの接続をまとめて使い回す仕組み)がオンのままコピーした場合です。
マイグレーションにはプーリングなしの接続を使うのがNeonの推奨なので、スイッチをオフにしてから接続文字列をコピーし直してください。
この画面は開き直すとスイッチがオンに戻るので、コピーする前にホスト名を確認します。
6.投稿できるのにCloudflare R2の画像が表示されない
エラーも出ないのに画像だけ表示されない場合は、保存するときのstore()に'r2'を書き忘れています。
作成と編集の両方を確認してください。
表示する側も、Storage::disk('r2')->url(…)でR2のURLを作っているかを合わせて確認します。
// 作成
'image_path' => $this->image?->store('posts', 'r2'),
// 編集
$data['image_path'] = $this->image->store('posts', 'r2');
Livewire(PHPだけで画面を動的に更新できるLaravel向けのライブラリ)で作っている場合、フォームで画像を選んだ時点で、投稿ボタンを押す前に画像をサーバーへ送り、一時的な場所に置きます。
store()で保存先を指定しないと、画像はLaravelの既定の保存先(何も設定していなければサーバーの中)に保存され、R2には届きません。
しかもエラーは出ないので、投稿は成功したように見えます。
Fly.ioのサーバーの中に保存した画像は、再起動やデプロイのたびに消えるので、保存先は必ずR2にします。
7.Cloudflare R2への画像の投稿でAccess Deniedと出る
画像を選んで投稿したときにエラーの画面が出て、fly logsにAccessDeniedやAccess Deniedと出る場合は、使っているAPIトークンに、そのバケット(R2でファイルを入れておく入れ物)へ書き込む権限がありません。
Cloudflareの「Manage API Tokens」の一覧で、次の2つを確認します。
- 「Applied to」が、今回使っているバケットになっているか
- 「Permission」が「Object Read & Write」になっているか
トークンを作るときの初期値は「Object Read only」なので、変え忘れるとこのエラーになります。
別のバケット用に作ったトークンの値を使ってしまった場合も同じです。
違っていたらトークンを作り直し、ローカルの.envとfly secrets setの値を新しいものに入れ替えてください。
8.Fly.ioのサーバーが2台になっている
Fly.ioは、初回のデプロイで予備も含めてサーバーを2台作ります。
初回のfly deployに--ha=false(サーバーを1台だけ作る指定)を付けないと2台になり、次の2つの問題が起きます。
- 料金が最大で2倍かかる
- 画像を選んだとき、または投稿したときにエラーになる
2つ目は、Livewireが画像を選んだ時点で先にサーバーへ送り、一時的に置いておく仕組みが原因です。
画像を選んだときのアクセスと、投稿ボタンを押したときのアクセスが別々のサーバーに届くと、2台目には一時的に置いた画像が無いので、投稿に失敗します。
fly statusでマシンが2行表示されていたら、次のコマンドで1台に減らしてください。
fly scale count 1
お客さんが使うサービスなどで、2台以上のまま動かしたい場合は、一時的な置き場所もR2にして、サーバーの中にファイルを残さないようにします。
php artisan livewire:publish --configで作ったconfig/livewire.phpの'temporary_file_upload'の'disk'を、nullから'r2'に変えます。
すると画像はブラウザからR2へ直接送られるので、R2のバケットのCORS(別のドメインのページからの送信を許可する設定)で、アプリのURLからのPUTを許可します。
一時的に置いた画像はバケットのlivewire-tmp/に残り続けるので、R2の「Object Lifecycle Rules」で、livewire-tmp/で始まるファイルを1日後に削除するルールも作ります。
SiiDの受講生は、Step 27.5の「サーバーを複数台にする場合」に詳しい手順があります。
9.Fly.ioのデータベースやRedisを作ってしまった
fly launchを--no-dbや--no-redisを付けずに実行すると、Fly.ioのデータベースやRedisが作られ、使っていなくても料金がかかり続けます。
次のコマンドで一覧を出し、表示されたIDや名前を指定して削除してください。
mpgはFly.ioのManaged Postgresのことです。
fly mpg list
fly mpg destroy <クラスタID>
fly redis list
fly redis destroy <名前>
LaravelのFly.io公開でエラーが出たときの確認先まとめ
症状 | 最初に見る場所 |
|---|
2.organization is suspended/数分で止まる | Fly.ioのBilling |
3.requires php >=8.4.1 | fly.tomlのPHP_VERSION
|
4.デザインが崩れる | bootstrap/app.phpのtrustProxies
|
5.500エラー・DBにつながらない | fly logs、fly secrets list
|
6.画像が表示されない | store()の'r2'
|
7.Access Denied | R2のAPIトークンの権限 |
8.料金が想定より高い・画像の投稿でエラー | fly statusの台数
|
9.使っていないDB・Redisの料金 | fly mpg list、fly redis list
|
どれにも当てはまらないときも、1のfly logsでエラーの文を確認し、その文で調べるのが近道です。
AIプログラミングスクール「SiiD」について
AIプログラミングスクール「SiiD」は、未経験からITエンジニア転職を目指す方向けのオンラインスクールです。
SiiDの特徴
- 現役エンジニアでYouTube登録者約13万人の「セイト先生」が代表兼主任講師
- 採用側の実務知見(2,000人以上の選考・150名以上のエンジニア採用)にもとづく指導
- 生成AIを取り入れた学習設計と、実務レベルのフルスタックWeb開発スキル
- Workship CAREER(株式会社GIG)と連携した無料の転職伴走支援
- 経済産業省認定のReスキル講座で、給付金の条件を満たせば実質105,600円〜
- 学割あり(35%オフ)
こんな方におすすめ
- 未経験・文系・社会人からITエンジニア転職を本気で目指したい方
- 独学に限界を感じている方
- 費用を抑えながら実務スキルと転職サポートを両立したい方
「未経験だから」とあきらめる必要はありません。採用する側を知り尽くしたプロが、給付金で負担を抑えながら内定まで伴走します。