Cloud Runデプロイ時にエラー
Container failed to start. Failed to start and then listen on the port defined by the PORT environment variable.
対処法
CloudRun起動時に、0.0.0.0:8080
に対してヘルスチェックが通らず、エラーとなっていた。
PORT
環境変数によって、portのマッピングを自動で設定してくれるが、未指定の場合、デフォルトで8080
となるそう。
serverのlistenしているポートが3000となっていたので、環境変数PORT
を読むように変更した。
問題のコード
func main() {
log.Print("starting server...")
http.HandleFunc("/", handler)
// Start HTTP server.
if err := http.ListenAndServe(":3000", nil); err != nil {
log.Fatal(err)
}
}
func handler(w http.ResponseWriter, r *http.Request) {
name := os.Getenv("NAME")
if name == "" {
name = "World"
}
fmt.Fprintf(w, "Hello %s!\n", name)
}
修正後
func main() {
log.Print("starting server...")
http.HandleFunc("/", handler)
// 追加
port := os.Getenv("PORT")
if port == "" {
port = "8080"
}
// Start HTTP server.
if err := http.ListenAndServe(":"+port, nil); err != nil {
log.Fatal(err)
}
}
func handler(w http.ResponseWriter, r *http.Request) {
name := os.Getenv("NAME")
if name == "" {
name = "World"
}
fmt.Fprintf(w, "Hello %s!\n", name)
}
デバッグ過程
今回のエラーに関しては、GCPのトラブルシューティングに沿ってデバッグした。
ありがたいmm
ステップ1
コンテナ イメージをローカルで実行できることを確認します。コンテナ イメージをローカルで実行できない場合は、まず問題をローカルで診断して修正する必要があります。
下記コマンド実行、https://localhost:3000
にアクセス。OK。
$ docker run -it IMAGE_NAME
ステップ2
コンテナ ランタイムの契約に記載されているように、コンテナが想定ポートでリクエストをリッスンしていることを確認します。コンテナは、Cloud Run によって定義され、PORT 環境変数で指定されているポートで受信リクエストをリッスンする必要があります。
下記のコマンド実行。https://localhost:8080
にアクセス。動かない、、
$ PORT=8080 && docker run -it IMAGE_NAME
main.goを見たら、portが即値で入っていました。。。
直して、無事動いた。
これでも動かない場合
公式のトラブルシューティングにてmm