🐴

Herokuへデプロイするのに、ポート番号まわりで失敗した話

2022/08/12に公開

問題

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