Herokuへデプロイするのに、ポート番号まわりで失敗した話
問題
LINE Messaging API SDK for Python を利用して LINE CHAT BOT を開発し、Herokuへデプロイしたときに生じた問題。
ボットサーバのエンドポイントとして設定したURLにPOSTリクエストを投げても反応がない。
localhostでテストしたときは問題なく動いていたのに...
ログ
heroku logs --tail
でログを見てみると、
2022-08-12T04:44:19.942449+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=POST path="/callback" host=******.herokuapp.com request_id=******** fwd="**.**.**.**" dyno= connect= service= status=503 bytes= protocol=https
とのこと。
Error Code : H10 で検索して、Herokuのエラーコードに関するドキュメントを読んでみると、
H10 - App crashed (アプリがクラッシュしました)
Web dyno のクラッシュや Web dyno でのブートタイムアウトにより、このエラーが表示されます。
とあるが、うーん、なんのこっちゃよくわからん。
ここで詰まってしまって、一度Heroku上のアプリを削除して、デプロイし直すことに。
(困ったときに最初からやり直す癖なくしたいんだけど、いかんせん原因がわからなさすぎて...)
$ heroku apps:destroy --app アプリ名
$ heroku create アプリ名
$ git push heroku main
しかし、状況は依然として変わらず。
そもそも、HTTP通信以外の部分で問題が発生しているのでは。と考え直し、ログをさらに遡っていると...
2022-08-12T04:44:17.061207+00:00 heroku[web.1]: Error R10 (Boot timeout) -> Web process failed to bind to $PORT within 60 seconds of launch
それっぽいものを発見。なにやら、ポート番号周辺の問題であったようだ。
原因
問題となっていたコードはここ↓
if __name__ == "__main__":
app.run()
Herokuはアプリケーションに割り当てるポート番号が動的であるため、固定できないらしい。アプリケーション側で設定しているポート番号と、Herokuが動的に設定したポート番号の不一致によって、プロセスが終了していた。
解決策
Herokuが割り当てたポート番号は、環境変数PORT
から取得できるので、os.environ.get()
関数を使って、アプリケーション側でも同じポート番号になるように設定してやる。
if __name__ == "__main__":
port = int(os.environ.get("PORT", 5000))
app.run(host="0.0.0.0", port=port)
Discussion