【Cloud Run】「ポートが原因?」と思いきや…リビジョン作成失敗の犯人は「関数のエントリポイント」の設定漏れだった話
WRITTEN BYMeg Google CloudのCloud Runデプロイ時に発生する「PORT=8080でタイムアウト」というエラーの解決策を解説します。表面的なメッセージとは異なり、真の原因はFunctions Frameworkにおける「関数のエントリポイント」の設定漏れにあることが多いです。Cloud Loggingを活用した原因特定の手順から、環境変数による修正方法まで、実体験に基づいたトラブルシューティングを紹介します。
はじめに
Google Cloudのハンズオンで、初めてCloud Runを触ってみたのですが、さっそくデプロイ(リビジョンの作成)で失敗してしまいました。
画面に表示されたエラーは以下の通りです。
「失敗。詳細: The user-provided container failed to start and listen on the port defined provided by the PORT=8080 environment variable within the allocated timeout.」
これを見ると、「ポートの設定ミスかな?」「コンテナの起動タイムアウトが短すぎるのかな?」と、ネットワークやコンテナ側の設定ばかりを疑ってしまいますよね。
しかし、原因を調べていくと「画面のエラー文言とは全く違う、初歩的な設定漏れ」が原因でした。同じ罠にハマった方の参考になれば幸いです!
発生したエラーの正体(ログの確認)
焦らずに、コンソール画面の「Cloud Logging を開く」から詳細なログ(stderr)を追いかけてみました。すると、一番下にこんなメッセージが記録されていました。
functions_framework.exceptions.MissingTargetException: File /workspace/main.py is expected to contain a function named 'hello_http'. Found: '[自分が定義した関数名]' instead
エラーを要約すると、「main.py の中には hello_http という関数があるはずなのに、実際には [自分が定義した関数名] しか見つからないよ!」 ということでした。
原因:「関数のエントリポイント」の設定漏れ
今回の真の原因は、デプロイ時に「関数のエントリポイント」を設定し忘れていたことでした。
PythonのコードをWebアプリとして動かす「Functions Framework」という仕組みでは、起動時に「最初に呼び出す関数(エントリポイント)」を指定する必要があります。これが未設定だと、デフォルトの hello_http という関数を探しに行ってしまいます。
つまり、今回のエラーの流れはこうです。
- デプロイ時に「関数のエントリポイント」を設定し忘れた(デフォルトの
hello_httpのままになった) main.pyの中には自分が作った[独自の関数名]しかないため、ミスマッチで起動直後にコードがクラッシュした- アプリが立ち上がらないので、当然ポート(8080)も開かない
- Cloud Run側からは「ポートが開かないままタイムアウトした」ように見えた
ポートの設定が悪いのではなく、エントリポイントの設定漏れでコードがコケていたことが本質的な原因だったのです。
解決策
Cloud Runの設定で、プログラム内の関数名と「関数のエントリポイント」の記述を一致させてあげればサクッと解決します。
修正方法:Cloud Run側に「エントリポイント」を教えてあげる
【Google Cloud コンソールから直す場合】
- Cloud Runのサービス詳細画面から 「新しいリビジョンの編集とデプロイ」 をクリック。
- 「コンテナ」 タブを開き、環境変数(Variables)の項目を探す。
- 以下の環境変数を追加して、エントリポイントを明示します。
- 名前(Name):
FUNCTION_TARGET - 値(Value):
[自分がmain.pyで定義した関数名]
- 再デプロイする。
まとめ
Cloud Runで「ポートが開かない」系のエラーが出たときは、ネットワーク設定をこねくり回す前に、まず Cloud Logging を開いて起動直後にコードがクラッシュしていないか確認するのが鉄則だと学びました。
表面的なエラーメッセージ(PORT=8080〜)に騙されず、ログをしっかり読めば「関数のエントリポイントの設定漏れ」という真犯人に辿り着くことができます。
同じエラーでデプロイが通らない方は、ぜひ設定を見直してみてください!
