Cloud Run Gen 2: Uncovering Port 80 Limitations for Container Startup

Cloud Run Gen 2: Uncovering Port 80 Limitations for Container Startup

English follows Japanese.

概要

Cloud Run の The second generation (Gen 2; 第2世代)は、Port 80 で待ち受けることができない。コンテナの起動チェックが失敗する。
Cloud Run の The first generation (Gen 1; 第1世代)では、Port 80 で待ち受けることができた。コンテナの起動チェックは成功する。
このことはドキュメントに書かれていないため、注意が必要である。

Cloud Run の世代は、Cloud Run functions の世代とは異なる。

前置き(長い)

Cloud Run は「サービス実行環境」として、第1世代 (The first generation) と第2世代 (The second generation) の2つの世代を提供している。これは、Cloud Run functions の Cloud Run functions(第1世代)と Cloud Run functions(第2世代)の違いとは 根本的に別のもの である。

Cloud Run functions については、第1世代は、App Engine と同等の環境で動いていたと推察されるもので、第2世代は、明言されているように、Cloud Run の上で動いている。第1世代と第2世代は(完全には)ソースコードの互換性がないため、移植には若干の手間がかかる。

Cloud Run については、第2世代が 2022-12-06 に GA となったことが発表された。NFS, NDB, 9P, CIFS/Samba, and Ceph をサポートし、このことで Cloud Filestore と Cloud Storage FUSE がサポートされるようになったと発表されている。第1世代は 2019-11-14 に GA となったことが発表されている。

第1世代と第2世代の違いはコンテナ ランタイムの契約というなんとも不思議なページで、解説されている。

第 1 世代の実行環境を使用する場合、Cloud Run コンテナは、gVisor コンテナ ランタイム サンドボックスを使用してサンドボックス化されます。gVisor syscall 互換性リファレンスに記載されているように、このコンテナ サンドボックスでは一部のシステムコールがサポートされていない場合があります。

第 2 世代の実行環境を使用している場合は、Linux との完全な互換性があります。Cloud Run ジョブは、常に第 2 世代の実行環境を使用します。第 2 世代の実行環境では、/sys/class/dmi/id/product_name は Google Compute Engine に設定されます。

第 2 世代の実行環境では、サービスコードが別のプロセス名前空間で実行されるため、特別なプロセス セマンティクスを持つコンテナ init プロセスとして開始されます。第 1 世代の実行環境では、サービスコードはコンテナ init プロセスとして実行されません。

Cloud Run は特権コンテナをサポートしていません。そのため、Cloud Run は、gcsfuse や sudo など、非 root ユーザーに対して setuid フラグを使用するバイナリをサポートしておらず、権限が不十分なために失敗する可能性があります。

問題の発生

結論から言うと、Port 80 で待ち受けていると外から接続ができない様子だったのだ。「特権」の問題で、Well-Known Port で待ち受けることができないのかもしれない。ただし、Cloud Run のドキュメントには、Port 80 で待ち受けることができないとは書いていない。

今回、あるコンテナを、第1世代から第2世代に変更したところ、次のようになった

  • 一見すると、コンテナは正常起動しているように見える
  • Startup Probe のアクセスログが出ていない
  • アクセスできなかったとして、Cloud Run のログにエラーが出ている

Rails 8 からは、Thruster が導入され、Port 80 で待ち受けるリバースプロキシと、背後で Port 3000 で待ち受ける Puma が標準の構成である。Thruster は、Port 80 で待ち受けているため、Container Port に 80 を指定していたが、Generation を Second に変更しただけで動作しなくなってしまった。

検証

あるサービス、structured-logging について、Execution environment Default から、Execution environment Second generation に変更した。その後、Cloud Logging のログを確認したところ、次のようなエラーが発生していた。

設定: Execution environment Second

検証1:

  • Execution environment: Second
  • Container Port: 80
  • Container:
    • Thruster: Port 80
    • Puma: Port 3000

結果1:

  • 起動プローブ失敗
2025-05-11 13:50:05.473 audit_log, method: "google.cloud.run.v1.Services.ReplaceService", principal_email: "test@example.com"
2025-05-11 13:50:20.308 {"http":":80", "level":"INFO", "msg":"Server started"}
2025-05-11 13:50:21.695 => Booting Puma
2025-05-11 13:50:21.695 => Rails 8.0.2 application starting in production 
2025-05-11 13:50:21.695 => Run `bin/rails server --help` for more startup options
2025-05-11 13:50:25.122 Puma starting in single mode...
2025-05-11 13:50:25.122 * Puma version: 6.6.0 ("Return to Forever")
2025-05-11 13:50:25.122 * Ruby version: ruby 3.4.3 (2025-04-14 revision d0b7e5b6a0) +YJIT +PRISM [x86_64-linux]
2025-05-11 13:50:25.123 *  Min threads: 3
2025-05-11 13:50:25.123 *  Max threads: 3
2025-05-11 13:50:25.123 *  Environment: production
2025-05-11 13:50:25.123 *          PID: 22
2025-05-11 13:50:25.123 * Listening on http://0.0.0.0:3000
2025-05-11 13:50:25.127 Use Ctrl-C to stop
2025-05-11 13:50:43.749 STARTUP HTTP probe failed 5 times consecutively for container "structured-logging-1" on port 80 path "/up". The instance was not started. Connection failed with status ERROR_CONNECTION_FAILED.
2025-05-11 13:50:45.162 Ready condition status changed to False for Revision structured-logging-00023-z99 with message: The user-provided container failed the configured startup probe checks. Logs for this revision might contain more information.  Logs URL: https://console.cloud.google.com/logs/viewer?project=rails8-gcexample&resource=cloud_run_revision/service_name/structured-logging/revision_name/structured-logging-00023-z99&advancedFilter=resource.type%3D%22cloud_run_revision%22%0Aresource.labels.service_name%3D%22structured-logging%22%0Aresource.labels.revision_name%3D%22structured-logging-00023-z99%22  For more troubleshooting guidance, see https://cloud.google.com/run/docs/troubleshooting#container-failed-to-start
2025-05-11 13:50:45.228 Ready condition status changed to False for Service structured-logging with message: Revision 'structured-logging-00023-z99' is not ready and cannot serve traffic. The user-provided container failed the configured startup probe checks. Logs for this revision might contain more information.  Logs URL: https://console.cloud.google.com/logs/viewer?project=rails8-gcexample&resource=cloud_run_revision/service_name/structured-logging/revision_name/structured-logging-00023-z99&advancedFilter=resource.type%3D%22cloud_run_revision%22%0Aresource.labels.service_name%3D%22structured-logging%22%0Aresource.labels.revision_name%3D%22structured-logging-00023-z99%22  For more troubleshooting guidance, see https://cloud.google.com/run/docs/troubleshooting#container-failed-to-start

このコンテナ(Rails 8.0.2 標準の構成)は、実は、直接 Port 3000 にアクセスすると、Thruster をバイパスして、直接 Puma にアクセスできるようになっている。よって、以下の設定を試してみた。諸事情で、別のサービス myapp で行った。

設定: 構成は変更せず、Container Port を 3000 に変更

検証2:

  • Execution environment: Second
  • Container Port: 3000
  • Container:
    • Thruster: Port 80
    • Puma: Port 3000

結果2:

  • 起動プローブ成功
2025-05-11T05:16:43.102033Z audit_log, method: "google.cloud.run.v1.Services.ReplaceService", principal_email: "test@example.com"
2025-05-11T05:16:50.568687Z GCSFuse is mounted with bucket myapp-database-2. Enable GCSFuse logging with mount options for more logs
2025-05-11T05:17:01.485709218Z {"http":":80", "level":"INFO", "msg":"Server started"}
2025-05-11T05:17:02.678599Z => Booting Puma
2025-05-11T05:17:02.678612Z => Rails 8.0.2 application starting in production
2025-05-11T05:17:02.678617Z => Run `bin/rails server --help` for more startup options
2025-05-11T05:17:05.612966Z Puma starting in single mode...
2025-05-11T05:17:05.612978Z * Puma version: 6.6.0 ("Return to Forever")
2025-05-11T05:17:05.612982Z * Ruby version: ruby 3.4.3 (2025-04-14 revision d0b7e5b6a0) +YJIT +PRISM [x86_64-linux]
2025-05-11T05:17:05.612985Z * Min threads: 3
2025-05-11T05:17:05.612988Z * Max threads: 3
2025-05-11T05:17:05.612991Z * Environment: production
2025-05-11T05:17:05.612994Z * PID: 21
2025-05-11T05:17:05.613469Z * Listening on http://0.0.0.0:3000
2025-05-11T05:17:05.619894Z Use Ctrl-C to stop
2025-05-11T05:17:06.376474Z STARTUP HTTP probe succeeded after 17 attempts for container "myapp-1" on port 3000 path "/up".
2025-05-11T05:17:06.471410Z Ready condition status changed to True for Revision myapp-00008-jp7 with message: Deploying revision succeeded in 22.32s.
2025-05-11T05:17:07.757828Z Ready condition status changed to True for Service myapp.

Thruster は Port 80 で待ちつつ、Startup probe は http://0.0.0.0:3000/up にアクセスして成功している。

Thruster は、環境変数 HTTP_PORT に 8080 を指定することで、ポートを変更できる Custom configuration。こちらを設定しても、問題はなかった(ログは割愛)。

最後に、Cloud Run がコンテナに期待する Port を 8080 に変更してみた。

設定:

  • HTTP_PORT に 8080 を指定
  • Container Port を 8080 に変更

検証3:

  • Execution environment: Second
  • Container Port: 8080
  • HTTP_PORT(Environment variable): 8080
  • Container:
    • Thruster: Port 8080
    • Puma: Port 3000

結果3:

  • 起動プローブ 成功
2025-05-11T05:33:25.954208Z audit_log, method: "google.cloud.run.v1.Services.ReplaceService", principal_email: "test@example.com"
2025-05-11T05:33:33.333447Z GCSFuse is mounted with bucket myapp-database-2. Enable GCSFuse logging with mount options for more logs
2025-05-11T05:33:44.494420644Z {"http":":8080", "level":"INFO", "msg":"Server started"}
2025-05-11T05:33:45.254073429Z {"error":"dial tcp 127.0.0.1:3000: connect: connection refused", "level":"INFO", "msg":"Unable to proxy request", "path":"/up"}
2025-05-11T05:33:45.254191640Z {"cache":"miss", "dur":5, "level":"INFO", "method":"GET", "msg":"Request", "path":"/up", "query":"", "remote_addr":"169.254.169.126:24517", "req_content_length":0, "req_content_type":"", "resp_content_length":0, "resp_content_type":"", "status":502, "user_agent":""}
2025-05-11T05:33:46.080122Z => Booting Puma
2025-05-11T05:33:46.080135Z => Rails 8.0.2 application starting in production
2025-05-11T05:33:46.080141Z => Run `bin/rails server --help` for more startup options
2025-05-11T05:33:46.255715515Z {"error":"dial tcp 127.0.0.1:3000: connect: connection refused", "level":"INFO", "msg":"Unable to proxy request", "path":"/up"}
2025-05-11T05:33:46.255862285Z {"cache":"miss", "dur":0, "level":"INFO", "method":"GET", "msg":"Request", "path":"/up", "query":"", "remote_addr":"169.254.169.126:15905", "req_content_length":0, "req_content_type":"", "resp_content_length":0, "resp_content_type":"", "status":502, "user_agent":""}
2025-05-11T05:33:47.257123378Z {"error":"dial tcp 127.0.0.1:3000: connect: connection refused", "level":"INFO", "msg":"Unable to proxy request", "path":"/up"}
2025-05-11T05:33:47.257210998Z {"cache":"miss", "dur":0, "level":"INFO", "method":"GET", "msg":"Request", "path":"/up", "query":"", "remote_addr":"169.254.169.126:9785", "req_content_length":0, "req_content_type":"", "resp_content_length":0, "resp_content_type":"", "status":502, "user_agent":""}
2025-05-11T05:33:48.258735601Z {"error":"dial tcp 127.0.0.1:3000: connect: connection refused", "level":"INFO", "msg":"Unable to proxy request", "path":"/up"}
2025-05-11T05:33:48.258832260Z {"cache":"miss", "dur":0, "level":"INFO", "method":"GET", "msg":"Request", "path":"/up", "query":"", "remote_addr":"169.254.169.126:28337", "req_content_length":0, "req_content_type":"", "resp_content_length":0, "resp_content_type":"", "status":502, "user_agent":""}
2025-05-11T05:33:49.260334673Z {"error":"dial tcp 127.0.0.1:3000: connect: connection refused", "level":"INFO", "msg":"Unable to proxy request", "path":"/up"}
2025-05-11T05:33:49.260409103Z {"cache":"miss", "dur":0, "level":"INFO", "method":"GET", "msg":"Request", "path":"/up", "query":"", "remote_addr":"169.254.169.126:58605", "req_content_length":0, "req_content_type":"", "resp_content_length":0, "resp_content_type":"", "status":502, "user_agent":""}
2025-05-11T05:33:49.770577Z Puma starting in single mode...
2025-05-11T05:33:49.770585Z * Puma version: 6.6.0 ("Return to Forever")
2025-05-11T05:33:49.770589Z * Ruby version: ruby 3.4.3 (2025-04-14 revision d0b7e5b6a0) +YJIT +PRISM [x86_64-linux]
2025-05-11T05:33:49.770592Z * Min threads: 3
2025-05-11T05:33:49.770595Z * Max threads: 3
2025-05-11T05:33:49.770598Z * Environment: production
2025-05-11T05:33:49.770601Z * PID: 21
2025-05-11T05:33:49.771009Z * Listening on http://0.0.0.0:3000
2025-05-11T05:33:49.777059Z Use Ctrl-C to stop
2025-05-11T05:33:50.268927329Z {"cache":"miss", "dur":7, "level":"INFO", "method":"GET", "msg":"Request", "path":"/up", "query":"", "remote_addr":"169.254.169.126:61639", "req_content_length":0, "req_content_type":"", "resp_content_length":73, "resp_content_type":"text/html; charset=utf-8", "status":200, "user_agent":""}
2025-05-11T05:33:50.269187Z STARTUP HTTP probe succeeded after 18 attempts for container "myapp-1" on port 8080 path "/up".
2025-05-11T05:33:50.344405Z Ready condition status changed to True for Revision myapp-00011-vj4 with message: Deploying revision succeeded in 23.43s.
2025-05-11T05:33:51.639467Z Ready condition status changed to True for Service myapp.

以上より、Container Port が 80 では失敗し、3000 では成功している。また、Thruster の Port を 8080 に変更して、Container Port も 8080 に変更したところ、成功している。よって、Cloud Run Gen 2 では、Port 80 で待ち受けることができないようだ。

参考文献


Overview

Cloud Run's The second generation (Gen 2) cannot listen on Port 80. The container startup check fails.
Cloud Run's The first generation (Gen 1) could listen on Port 80. The container startup check succeeds.
This is not written in the documentation, so caution is necessary.

The generation of Cloud Run is different from the generation of Cloud Run functions.

Preamble (long)

Cloud Run offers two generations as a "service execution environment": The first generation and The second generation. This is fundamentally different from the difference between Cloud Run functions (1st gen) and Cloud Run functions (2nd gen) of Cloud Run functions.

Regarding Cloud Run functions, it is presumed that the 1st generation ran in an environment equivalent to App Engine, and the 2nd generation, as explicitly stated, runs on Cloud Run. The 1st and 2nd generations are not (completely) source code compatible, so porting requires some effort.

Regarding Cloud Run, it was announced that the 2nd generation became GA on 2022-12-06. It was announced that it supports NFS, NDB, 9P, CIFS/Samba, and Ceph, and that this has led to support for Cloud Filestore and Cloud Storage FUSE. It was announced that the 1st generation became GA on 2019-11-14.

The difference between the 1st and 2nd generations is explained on a rather mysterious page called Container runtime contract.

When using the 1st generation execution environment, Cloud Run containers are sandboxed using the gVisor container runtime sandbox. As noted in the gVisor syscall compatibility reference, this container sandbox may not support some system calls.

If you are using the 2nd generation execution environment, you have full Linux compatibility. Cloud Run jobs always use the 2nd generation execution environment. In the 2nd generation execution environment, /sys/class/dmi/id/product_name is set to Google Compute Engine.

In the 2nd generation execution environment, your service code runs in a separate process namespace, so it starts as a container init process with special process semantics. In the 1st generation execution environment, your service code does not run as a container init process.

Cloud Run does not support privileged containers. Therefore, Cloud Run does not support binaries that use the setuid flag for non-root users, such as gcsfuse or sudo, and may fail due to insufficient permissions.

Occurrence of the problem

To put it bluntly, it seemed that connections from the outside could not be made when listening on Port 80. It might be a "privilege" issue, making it impossible to listen on a Well-Known Port. However, the Cloud Run documentation does not state that it is impossible to listen on Port 80.

This time, when I changed a certain container from the 1st generation to the 2nd generation, the following happened:

  • At first glance, the container appears to be starting normally.
  • There are no access logs for the Startup Probe.
  • An error appears in the Cloud Run logs, indicating that access was not possible.

Since Rails 8, Thruster has been introduced, and the standard configuration is a reverse proxy listening on Port 80 and Puma listening on Port 3000 behind it. Thruster was listening on Port 80, so I had specified 80 for the Container Port, but it stopped working just by changing the Generation to Second.

Verification

For a service, structured-logging, I changed the Execution environment from Default to Execution environment Second generation. After that, when I checked the Cloud Logging logs, the following error had occurred.

Setting: Execution environment Second

Verification 1:

  • Execution environment: Second
  • Container Port: 80
  • Container:
    • Thruster: Port 80
    • Puma: Port 3000

Result 1:

  • Startup probe failed
2025-05-11 13:50:05.473 audit_log, method: "google.cloud.run.v1.Services.ReplaceService", principal_email: "test@example.com"
2025-05-11 13:50:20.308 {"http":":80", "level":"INFO", "msg":"Server started"}
2025-05-11 13:50:21.695 => Booting Puma
2025-05-11 13:50:21.695 => Rails 8.0.2 application starting in production 
2025-05-11 13:50:21.695 => Run `bin/rails server --help` for more startup options
2025-05-11 13:50:25.122 Puma starting in single mode...
2025-05-11 13:50:25.122 * Puma version: 6.6.0 ("Return to Forever")
2025-05-11 13:50:25.122 * Ruby version: ruby 3.4.3 (2025-04-14 revision d0b7e5b6a0) +YJIT +PRISM [x86_64-linux]
2025-05-11 13:50:25.123 *  Min threads: 3
2025-05-11 13:50:25.123 *  Max threads: 3
2025-05-11 13:50:25.123 *  Environment: production
2025-05-11 13:50:25.123 *          PID: 22
2025-05-11 13:50:25.123 * Listening on http://0.0.0.0:3000
2025-05-11 13:50:25.127 Use Ctrl-C to stop
2025-05-11 13:50:43.749 STARTUP HTTP probe failed 5 times consecutively for container "structured-logging-1" on port 80 path "/up". The instance was not started. Connection failed with status ERROR_CONNECTION_FAILED.
2025-05-11 13:50:45.162 Ready condition status changed to False for Revision structured-logging-00023-z99 with message: The user-provided container failed the configured startup probe checks. Logs for this revision might contain more information.  Logs URL: https://console.cloud.google.com/logs/viewer?project=rails8-gcexample&resource=cloud_run_revision/service_name/structured-logging/revision_name/structured-logging-00023-z99&advancedFilter=resource.type%3D%22cloud_run_revision%22%0Aresource.labels.service_name%3D%22structured-logging%22%0Aresource.labels.revision_name%3D%22structured-logging-00023-z99%22  For more troubleshooting guidance, see https://cloud.google.com/run/docs/troubleshooting#container-failed-to-start
2025-05-11 13:50:45.228 Ready condition status changed to False for Service structured-logging with message: Revision 'structured-logging-00023-z99' is not ready and cannot serve traffic. The user-provided container failed the configured startup probe checks. Logs for this revision might contain more information.  Logs URL: https://console.cloud.google.com/logs/viewer?project=rails8-gcexample&resource=cloud_run_revision/service_name/structured-logging/revision_name/structured-logging-00023-z99&advancedFilter=resource.type%3D%22cloud_run_revision%22%0Aresource.labels.service_name%3D%22structured-logging%22%0Aresource.labels.revision_name%3D%22structured-logging-00023-z99%22  For more troubleshooting guidance, see https://cloud.google.com/run/docs/troubleshooting#container-failed-to-start

This container (standard Rails 8.0.2 configuration) can actually be accessed directly on Port 3000, bypassing Thruster and accessing Puma directly. Therefore, I tried the following settings. For various reasons, I did this with a different service, myapp.

Setting: Configuration unchanged, Container Port changed to 3000

Verification 2:

  • Execution environment: Second
  • Container Port: 3000
  • Container:
    • Thruster: Port 80
    • Puma: Port 3000

Result 2:

  • Startup probe succeeded
2025-05-11T05:16:43.102033Z audit_log, method: "google.cloud.run.v1.Services.ReplaceService", principal_email: "test@example.com"
2025-05-11T05:16:50.568687Z GCSFuse is mounted with bucket myapp-database-2. Enable GCSFuse logging with mount options for more logs
2025-05-11T05:17:01.485709218Z {"http":":80", "level":"INFO", "msg":"Server started"}
2025-05-11T05:17:02.678599Z => Booting Puma
2025-05-11T05:17:02.678612Z => Rails 8.0.2 application starting in production
2025-05-11T05:17:02.678617Z => Run `bin/rails server --help` for more startup options
2025-05-11T05:17:05.612966Z Puma starting in single mode...
2025-05-11T05:17:05.612978Z * Puma version: 6.6.0 ("Return to Forever")
2025-05-11T05:17:05.612982Z * Ruby version: ruby 3.4.3 (2025-04-14 revision d0b7e5b6a0) +YJIT +PRISM [x86_64-linux]
2025-05-11T05:17:05.612985Z * Min threads: 3
2025-05-11T05:17:05.612988Z * Max threads: 3
2025-05-11T05:17:05.612991Z * Environment: production
2025-05-11T05:17:05.612994Z * PID: 21
2025-05-11T05:17:05.613469Z * Listening on http://0.0.0.0:3000
2025-05-11T05:17:05.619894Z Use Ctrl-C to stop
2025-05-11T05:17:06.376474Z STARTUP HTTP probe succeeded after 17 attempts for container "myapp-1" on port 3000 path "/up".
2025-05-11T05:17:06.471410Z Ready condition status changed to True for Revision myapp-00008-jp7 with message: Deploying revision succeeded in 22.32s.
2025-05-11T05:17:07.757828Z Ready condition status changed to True for Service myapp.

Thruster is listening on Port 80, while the Startup probe accesses http://0.0.0.0:3000/up and succeeds.

Thruster can change its port by specifying 8080 for the environment variable HTTP_PORTCustom configuration. There was no problem even when this was set (logs omitted).

Finally, I tried changing the Port that Cloud Run expects from the container to 8080.

Setting:

  • Specify 8080 for HTTP_PORT
  • Change Container Port to 8080

Verification 3:

  • Execution environment: Second
  • Container Port: 8080
  • HTTP_PORT(Environment variable): 8080
  • Container:
    • Thruster: Port 8080
    • Puma: Port 3000

Result 3:

  • Startup probe succeeded
2025-05-11T05:33:25.954208Z audit_log, method: "google.cloud.run.v1.Services.ReplaceService", principal_email: "test@example.com"
2025-05-11T05:33:33.333447Z GCSFuse is mounted with bucket myapp-database-2. Enable GCSFuse logging with mount options for more logs
2025-05-11T05:33:44.494420644Z {"http":":8080", "level":"INFO", "msg":"Server started"}
2025-05-11T05:33:45.254073429Z {"error":"dial tcp 127.0.0.1:3000: connect: connection refused", "level":"INFO", "msg":"Unable to proxy request", "path":"/up"}
2025-05-11T05:33:45.254191640Z {"cache":"miss", "dur":5, "level":"INFO", "method":"GET", "msg":"Request", "path":"/up", "query":"", "remote_addr":"169.254.169.126:24517", "req_content_length":0, "req_content_type":"", "resp_content_length":0, "resp_content_type":"", "status":502, "user_agent":""}
2025-05-11T05:33:46.080122Z => Booting Puma
2025-05-11T05:33:46.080135Z => Rails 8.0.2 application starting in production
2025-05-11T05:33:46.080141Z => Run `bin/rails server --help` for more startup options
2025-05-11T05:33:46.255715515Z {"error":"dial tcp 127.0.0.1:3000: connect: connection refused", "level":"INFO", "msg":"Unable to proxy request", "path":"/up"}
2025-05-11T05:33:46.255862285Z {"cache":"miss", "dur":0, "level":"INFO", "method":"GET", "msg":"Request", "path":"/up", "query":"", "remote_addr":"169.254.169.126:15905", "req_content_length":0, "req_content_type":"", "resp_content_length":0, "resp_content_type":"", "status":502, "user_agent":""}
2025-05-11T05:33:47.257123378Z {"error":"dial tcp 127.0.0.1:3000: connect: connection refused", "level":"INFO", "msg":"Unable to proxy request", "path":"/up"}
2025-05-11T05:33:47.257210998Z {"cache":"miss", "dur":0, "level":"INFO", "method":"GET", "msg":"Request", "path":"/up", "query":"", "remote_addr":"169.254.169.126:9785", "req_content_length":0, "req_content_type":"", "resp_content_length":0, "resp_content_type":"", "status":502, "user_agent":""}
2025-05-11T05:33:48.258735601Z {"error":"dial tcp 127.0.0.1:3000: connect: connection refused", "level":"INFO", "msg":"Unable to proxy request", "path":"/up"}
2025-05-11T05:33:48.258832260Z {"cache":"miss", "dur":0, "level":"INFO", "method":"GET", "msg":"Request", "path":"/up", "query":"", "remote_addr":"169.254.169.126:28337", "req_content_length":0, "req_content_type":"", "resp_content_length":0, "resp_content_type":"", "status":502, "user_agent":""}
2025-05-11T05:33:49.260334673Z {"error":"dial tcp 127.0.0.1:3000: connect: connection refused", "level":"INFO", "msg":"Unable to proxy request", "path":"/up"}
2025-05-11T05:33:49.260409103Z {"cache":"miss", "dur":0, "level":"INFO", "method":"GET", "msg":"Request", "path":"/up", "query":"", "remote_addr":"169.254.169.126:58605", "req_content_length":0, "req_content_type":"", "resp_content_length":0, "resp_content_type":"", "status":502, "user_agent":""}
2025-05-11T05:33:49.770577Z Puma starting in single mode...
2025-05-11T05:33:49.770585Z * Puma version: 6.6.0 ("Return to Forever")
2025-05-11T05:33:49.770589Z * Ruby version: ruby 3.4.3 (2025-04-14 revision d0b7e5b6a0) +YJIT +PRISM [x86_64-linux]
2025-05-11T05:33:49.770592Z * Min threads: 3
2025-05-11T05:33:49.770595Z * Max threads: 3
2025-05-11T05:33:49.770598Z * Environment: production
2025-05-11T05:33:49.770601Z * PID: 21
2025-05-11T05:33:49.771009Z * Listening on http://0.0.0.0:3000
2025-05-11T05:33:49.777059Z Use Ctrl-C to stop
2025-05-11T05:33:50.268927329Z {"cache":"miss", "dur":7, "level":"INFO", "method":"GET", "msg":"Request", "path":"/up", "query":"", "remote_addr":"169.254.169.126:61639", "req_content_length":0, "req_content_type":"", "resp_content_length":73, "resp_content_type":"text/html; charset=utf-8", "status":200, "user_agent":""}
2025-05-11T05:33:50.269187Z STARTUP HTTP probe succeeded after 18 attempts for container "myapp-1" on port 8080 path "/up".
2025-05-11T05:33:50.344405Z Ready condition status changed to True for Revision myapp-00011-vj4 with message: Deploying revision succeeded in 23.43s.
2025-05-11T05:33:51.639467Z Ready condition status changed to True for Service myapp.

From the above, Container Port 80 fails, while 3000 succeeds. Also, changing Thruster's Port to 8080 and also changing the Container Port to 8080 resulted in success. Therefore, it seems that Cloud Run Gen 2 cannot listen on Port 80.

References