Cloud Runのポート8080エラー?

Cloud runの8008エラー DX化
Cloud runの8008エラー

「Cloud Runデプロイ時のポート8080のエラー?」

The user-provided container failed to start and listen on the port defined provided by the PORT=8080 environment variable within the allocated timeout. This can happen when the container port is misconfigured or if the timeout is too short. The health check timeout can be extended.

エラーメッセージに「PORT=8080」の文字を見て、ポート設定の問題だと何時間も格闘しました。しかし、真の原因は別のところにありました。

Cloud Run ポート 8080 エラーでつまづいた話

「ポートの問題」だと思い込んでハマった理由

ポート関連のエラーだと思い込んでしまった主な理由

  1. ローカルで動作するのにCloud Runでは失敗する:開発環境では問題なく動作するアプリケーションが、Cloud Runにデプロイするとエラーになるのでビルドエラーだと気付かなかった。
  2. エラーメッセージに「PORT=8080」の記述がある:「Container failed to start and listen on the port defined…」というメッセージを見ると、ポート設定に問題があると直感的に判断してしまった。
  3. エラー表示がこのポートエラーのみだった:このポートエラー以外のログのみエラー表示され、真の原因になったログはエラー表示されていなかった。

Cloud Run 用に正しくポート設定する方法

まずは、Cloud Runでアプリケーションを正しく動作させるためのポート設定について確認します。

  1. DockerfileへのEXPOSE 8080の記述:これはDockerコンテナがどのポートで通信するかをドキュメント化するためのもので、実際の動作には影響しませんが、明示しておくとよいでしょう。
# DockerfileのEXPOSE設定例
FROM node:18
WORKDIR /app
COPY . .
RUN npm install
EXPOSE 8080  # ← これはドキュメンテーション目的
CMD ["npm", "start"]
  1. アプリケーションコードでの環境変数の利用:Node.jsアプリケーションの場合、以下のようにして環境変数PORTを読み取り、フォールバック値も設定します。
// Node.jsでのポート設定例
const express = require('express');
const app = express();
const port = process.env.PORT || 8080;

const PORT = process.env.PORT ? parseInt(process.env.PORT, 10) : 8080;
app.listen(PORT, '0.0.0.0', () => {
  console.log(`Server listening on port ${PORT}`);
});

これらの設定を行っても、なおCloud Runのデプロイに失敗する場合は、ポート以外の問題を疑う必要があります。

実際に出たエラーログとその対応

実際のエラーログを詳しく見ていくと、ポート問題ではなく別の原因が浮かび上がってきます。

firebase: not found → Firebase CLI が Docker に入っていない

以下のようなエラーログが表示される場合:

2025-04-28 11:58:21.697 JST sh: 1: firebase: not found
2025-04-28 11:58:21.865 JST Container called exit(127).

このエラーは「firebaseコマンドが見つからない」ことを示しています。つまり、Firebase CLIがDockerコンテナ内にインストールされていないのです。

対応策DockerfileにFirebase CLIのインストールコマンドを追加します。

FROM node:18
WORKDIR /app
COPY . .
RUN npm install
# Firebase CLIをグローバルにインストール
RUN npm install -g firebase-tools
EXPOSE 8080
CMD ["npm", "start"]

※ただし、この対応策を実装する前に、そもそもDockerコンテナ内でFirebase CLIが必要かどうかを検討してください。Cloud Run単体のアプリケーションであれば、Firebase CLIは不要かもしれません。

firebase.json がない → Cloud Functions 向けコマンドが不要だった

続いて、次のようなエラーが発生

DEFAULT 2025-04-28T03:52:31.232368Z > start
DEFAULT 2025-04-28T03:52:31.232390Z > npm run shell
DEFAULT 2025-04-28T03:52:31.446314Z > shell
DEFAULT 2025-04-28T03:52:31.446325Z > npm run build && firebase functions:shell
DEFAULT 2025-04-28T03:52:31.661193Z > build
DEFAULT 2025-04-28T03:52:31.661202Z > tsc
WARNING 2025-04-28T03:52:45.262556516Z Container called exit(1).
DEFAULT 2025-04-28T03:52:45.262634Z Error: Not in a Firebase app directory (could not locate firebase.json)

このエラーは、package.jsonstartスクリプト内でfirebase functions:shellコマンドが実行されているにもかかわらず、Firebase設定ファイル(firebase.json)が見つからないことを示しています。

原因: Cloud Functions用の起動スクリプトが混入しています。これは、当初Cloud Functions向けに開発を進めていたため、コードの修正忘れが原因でした。

対応策package.jsonのスクリプトセクションを見直し、Cloud Run用に適切に設定します。

// package.jsonの修正例
{
  "scripts": {
    "build": "tsc",
    "start": "npm run build && node dist/index.js"  // ← firebase functions:shellを削除
  }
}

Cloud Runでは単純にビルドしたアプリケーションを起動するだけで良いので、Firebase関連のコマンドは削除します。

npm run shell → shellスクリプトが存在しない or 不要だった

DEFAULT 2025-04-28T03:52:31.232368Z > start
DEFAULT 2025-04-28T03:52:31.232390Z > npm run shell
・・・
DEFAULT 2025-04-28T03:52:45.262634Z Error: Not in a Firebase app directory (could not locate firebase.json)

これはpackage.jsonstartスクリプトがnpm run shellを呼び出しているのに、そのスクリプトが正しく設定されていないか、Cloud Run環境では不要であることを示しています。こちらもコードの修正忘れが原因でした。

対応策package.jsonのスクリプト設定を整理

{
  "scripts": {
    "build": "tsc",
    "start": "node dist/index.js"  // シンプルに実行ファイルを指定
  }
}

もし、Cloud RunとCloud Functionsで同じコードベースを使用している場合は、環境ごとに異なる起動スクリプトを用意するとよいと思います。

{
  "scripts": {
    "build": "tsc",
    "start": "node dist/index.js",  // Cloud Run用
    "start:functions": "firebase functions:shell"  // Cloud Functions開発用
  }
}

まとめ

Cloud Run上のアプリケーションでポート8080関連のエラーの場合、真の原因はポート設定自体ではなく、アプリケーションの起動プロセスに問題がある可能性が高いです。

今回の、エラーの原因は以下の通りでした。

  1. 不要なFirebaseコマンドが含まれている:Cloud Functions用のコマンドがCloud Run環境で実行されている
  2. ビルドと実行の不整合:開発環境と本番環境での設定の違いが考慮されていない
  3. 必要な依存関係や環境変数の不足:環境変数などの必要な設定が不足している

結局はログ確認ですね。今回、最初にビルドに失敗した原因のログがエラー表示されていなかったのが躓いた原因でした。その後ろにもビルドエラーが隠されていました…