「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 エラーでつまづいた話
「ポートの問題」だと思い込んでハマった理由
ポート関連のエラーだと思い込んでしまった主な理由
Cloud Run 用に正しくポート設定する方法
まずは、Cloud Runでアプリケーションを正しく動作させるためのポート設定について確認します。
Dockerfile
へのEXPOSE 8080
の記述:これはDockerコンテナがどのポートで通信するかをドキュメント化するためのもので、実際の動作には影響しませんが、明示しておくとよいでしょう。
# DockerfileのEXPOSE設定例
FROM node:18
WORKDIR /app
COPY . .
RUN npm install
EXPOSE 8080 # ← これはドキュメンテーション目的
CMD ["npm", "start"]
- アプリケーションコードでの環境変数の利用: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.json
のstart
スクリプト内で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.json
のstart
スクリプトが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関連のエラーの場合、真の原因はポート設定自体ではなく、アプリケーションの起動プロセスに問題がある可能性が高いです。
今回の、エラーの原因は以下の通りでした。
結局はログ確認ですね。今回、最初にビルドに失敗した原因のログがエラー表示されていなかったのが躓いた原因でした。その後ろにもビルドエラーが隠されていました…