SiiD BLOG ロゴ

LaravelをFly.ioで公開するときのよくあるエラーと対処法9つ【Neon・Cloudflare R2】

LaravelをFly.ioで公開するときのよくあるエラーと対処法9つ【Neon・Cloudflare R2】

この記事を書いた人

セイト@エンジニア兼講師

セイト@エンジニア兼講師

2012年に大学を卒業後、株式会社LIGにてWebデザイナー・Webエンジニアを3年務めたあと、株式会社LIG Philippinesの代表・VPoEとして6年間の在籍中に社員数約100名程度のテックチームへ成長させる。 その後2021年に独立し、合同会社BugFixを設立。登録者13万人を超えるテック系YouTubeチャンネルの運営やキャリアに特化したAIプログラミングスクールSiiDを運営中。

こんにちは!SiiD代表エンジニアのセイトです。

弊スクールではWebアプリの開発カリキュラムにおいて、Laravelで作ったアプリをfly.io・Neon・Cloudflare R2にデプロイする方法をお教えしていますが、この辺りの操作では躓くポイントがいくつかあります。

そこで本記事ではエラーごとの原因と直し方をまとめました。
起きる場面ごとに分けているので、自分の症状に近い見出しから読んでください。

1.Fly.ioのエラーは、まずfly logsとfly statusで原因を絞り込む

Fly.ioで公開したLaravelアプリは、本番環境なのでブラウザにエラーの詳しい内容が表示されません。
「Server Error」のような画面だけでは原因がわからないので、最初にターミナルで次の2つを見ます。

fly logs

fly logsは、Fly.ioのサーバーで動いているアプリのログを表示するコマンドです。
Laravelのエラーもここに流れてきます。
ログは止めるまで流れ続けるので、fly logsを実行したまま、ブラウザでエラーが出る操作をもう一度行い、流れてきた行を見ます。
終わったらCtrl+Cで止めます。

fly status

fly statusは、アプリの今の状態を表示するコマンドです。
Fly.ioではサーバーのことを「マシン」と呼び、このコマンドで何台のマシンがどの状態で動いているかを確認できます。
8の「サーバーが2台になっている」問題も、ここで見つけられます。

2.fly launchでorganization is suspendedと出る/公開した後、数分でサーバーが止まる

fly launchでorganization is suspendedと出た場合は、Fly.ioの支払い情報に問題があります。
公開した後、アクセスしている最中でも5分ほどでサーバーが止まる場合も、原因はクレジットカードの未登録です。
Fly.ioには無料枠がなく、カード未登録のトライアルでは、アクセスがあってもサーバーが5分で止まり、合計2時間か登録から7日で使えなくなります。
ダッシュボードのBillingを開き、カードが登録されているか、有効期限が切れていないかを確認してください。

なお、カードを登録していても、fly launchの初期設定では、数分アクセスがないとサーバーは自動で止まります。
これは料金を抑えるための正常な動きで、次のアクセスで起動します。
止まった後の最初の表示だけ、起動を待つので数秒遅くなります。

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つを確認します。

  1. fly secrets listにDB_CONNECTIONとDB_URLがあるか
  2. 貼ったNeonの接続文字列が、postgresql://から最後まで欠けずに入っているか
  3. 接続文字列のホスト名に-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エンジニア転職を本気で目指したい方
  • 独学に限界を感じている方
  • 費用を抑えながら実務スキルと転職サポートを両立したい方

「未経験だから」とあきらめる必要はありません。採用する側を知り尽くしたプロが、給付金で負担を抑えながら内定まで伴走します。

シェアする

未経験からのエンジニア転職を本気で目指すなら「SiiD」

SiiDはYouTube 13万人のセイト先生が主任講師のAIプログラミングスクール。元人事部長&現役エンジニアによる徹底指導で、生涯年収を大きくアップさせませんか?

SiiDの詳細を見る