Zeabur から Google Cloud Run へ:Dockerfile なしで移行、実際にデプロイした手順

Zeabur で GitHub から直接デプロイしていた Dockerfile なしのバックエンドは、ソースからのデプロイで Cloud Run に移せます。実際に 1 度デプロイし、Secret の権限エラーとその直し方もあわせてまとめました。

要点

  • Dockerfile は不要:--source を付けてデプロイすると、buildpacks が言語を自動判定する。
  • キーは Secret Manager に置き、--set-secrets でマウントする。サービスアカウントには Secret Manager Secret Accessor ロールが必要。
  • Cloud Run のファイルシステムは一時的。アップロードファイルは Cloud Storage や R2 に保存する。
  • 移行後は LINE Developers で Webhook URL を更新する。
この記事の検証方法(実機検証 3 件、公式ドキュメント準拠 3 件)
実際に検証した内容
  • Dockerfile のない Node サービスを、ソースからのデプロイで asia-east1 にデプロイし、URL が正常に応答(検証後に削除)
  • --set-env-vars で環境変数、--set-secrets で Secret Manager の値を設定し、アプリから読み取れることを確認
  • サービスアカウントに Secret の権限がないときのエラーと、権限付与後の再デプロイ成功
公式ドキュメントに基づく内容(未検証)
  • まっさらな GCP プロジェクトで有効化する API と付与するロール:既存プロジェクトで検証したため、この部分は Google の公式ドキュメントに基づいています
  • LINE Developers コンソールの操作:自社で LINE Bot を運用している経験に基づくもので、今回の検証ではやり直していません
  • カスタムドメインの設定:未検証。Google の公式ドキュメントに従ってください
目次(8 項目)
  1. 向いているケース
  2. ステップ 0:新規プロジェクトの準備(公式ドキュメントに基づく)
  3. ステップ 1:アプリが PORT を待ち受けているか確認
  4. ステップ 2:デプロイ
  5. ステップ 3:キーは環境変数ではなく Secret Manager に
  6. ステップ 4:データベース
  7. ステップ 5:LINE Bot の Webhook URL を変更
  8. ステップ 6:独自ドメインの設定

向いているケース

  • Zeabur で GitHub からデプロイしているバックエンド:Node.js・Python・Go の API、LINE Bot、Discord Bot
  • アクセスが少なく、誰も使っていないときは料金がかからないようにしたい(Cloud Run はゼロまでスケールダウンします)
  • 近いリージョンを使いたい:日本のユーザーが中心なら asia-northeast1(東京)。以下の例では検証に使った asia-east1(台湾)を記載しています

向いていないケース:永続ディスクが必要なサービス(アップロードファイルをローカルフォルダに保存するなど)。Cloud Run のファイルシステムは一時的なもので、再デプロイやゼロへのスケールダウンの後には書き込んだファイルが消えます。このようなサービスはファイルを Cloud Storage や R2 に保存するよう変更するか、VPS を使ってください(n8n 編を参照)。

ステップ 0:新規プロジェクトの準備(公式ドキュメントに基づく)

  1. gcloud CLI をインストールし、gcloud init でログインしてプロジェクトを選びます。プロジェクトには請求先アカウントの紐付けが必要です
  2. API を有効にします。
gcloud services enable run.googleapis.com cloudbuild.googleapis.com
  1. ソースからデプロイする場合、Cloud Build はデフォルトで Compute Engine のデフォルトサービスアカウントを使います。公式ドキュメントでは、このアカウントに Cloud Run Builder ロールを付与するよう求めています。
gcloud projects add-iam-policy-binding プロジェクトID \
  --member=serviceAccount:プロジェクト番号[email protected] \
  --role=roles/run.builder

ドキュメントによると、この権限付与が反映されるまで数分かかります。

今どのプロジェクトを使っているか必ず確認してください。 すべての gcloud コマンドに --project=プロジェクトID を付けるか、先に gcloud config get-value project で確認します。私たち自身のパソコンにも複数のプロジェクトがあり、デフォルトのプロジェクトがデプロイしたいものと違うことはよくあります。

ステップ 1:アプリが PORT を待ち受けているか確認

Zeabur も Cloud Run も、どのポートで待ち受けるかを環境変数 PORT でアプリに伝えます。Zeabur のドキュメントどおりにすでに $PORT を使っているなら、変更は不要です。3000 のようにハードコードしている場合は次のように変更します。

app.listen(process.env.PORT || 3000);

ステップ 2:デプロイ

プロジェクトのルートで実行します(Dockerfile は不要で、Google の buildpacks が言語を自動判定します)。

gcloud run deploy my-api --source . --region asia-east1 \
  --allow-unauthenticated \
  --set-env-vars "NODE_ENV=production" \
  --project=プロジェクトID

完了すると Service URL: https://my-api-xxxx.asia-east1.run.app が表示されます。検証では、Dockerfile のない Node サービスが初回のデプロイで正常に応答しました。

プロジェクトのルートに Dockerfile があれば、Cloud Run はそちらを優先して使います。

ステップ 3:キーは環境変数ではなく Secret Manager に

--set-env-vars の値は、サービスの設定を閲覧できる人なら誰でも見られます。データベースのパスワードや API キーは Secret Manager に入れてください。

# Secret を作成(printf なら末尾に改行が入らない)
printf '%s' 'postgresql://...' | gcloud secrets create database-url --data-file=- --project=プロジェクトID

# サービスにマウント。アプリからは従来どおり process.env.DATABASE_URL で読める
gcloud run services update my-api --region asia-east1 \
  --set-secrets "DATABASE_URL=database-url:latest" --project=プロジェクトID

検証で遭遇したエラー

サービスアカウントに Secret を読む権限がないと、デプロイは失敗します。

ERROR: (gcloud.run.deploy) ... Permission denied on secret: projects/.../secrets/database-url/versions/latest
for Revision service account [email protected]. The service account used must be granted
the 'Secret Manager Secret Accessor' role (roles/secretmanager.secretAccessor) at the secret, project or higher level.

対処法は、その Secret だけに権限を付与し(最小の範囲)、再デプロイすることです。

gcloud secrets add-iam-policy-binding database-url \
  --member="serviceAccount:エラーメッセージに出ているサービスアカウント" \
  --role="roles/secretmanager.secretAccessor" --project=プロジェクトID

検証では、権限を付与して再デプロイすると、すぐに成功しました。

ステップ 4:データベース

Cloud Run にはデータベースは含まれていません。PostgreSQL は Neon や Supabase などのマネージドサービス、または Google の Cloud SQL に移せます。移行方法はデータベース編を参照してください。

ステップ 5:LINE Bot の Webhook URL を変更

  1. LINE Developers を開き、チャネルを選択します
  2. 「Messaging API設定」タブの Webhook URL を、新しい Cloud Run の URL(アプリのパス、例:/webhook を付けたもの)に変更します
  3. 「検証」を押して成功を確認します

チャネルシークレットとチャネルアクセストークンも、この機会に差し替えることをおすすめします。セキュリティ編を参照してください。

ステップ 6:独自ドメインの設定

Cloud Run に独自ドメインを設定する方法は複数あり(Cloud Run のドメインマッピング、ロードバランサ、Firebase Hosting)、対応リージョンや費用が異なります。Google の公式ドキュメントを参照して選んでください。この手順は今回検証していません。 DNS 切り替えの注意点はドメインと DNS 編を参照してください。

よくある質問

Zeabur で Dockerfile なしで動かしていたプロジェクトを Cloud Run にデプロイできますか?

できます。ソースからのデプロイ(--source)では、Dockerfile がなければ Google Cloud の buildpacks が言語を判定してビルドします。Node.js のサービスで検証したところ、初回のデプロイで成功しました。

Cloud Run で Permission denied on secret と出たらどうすればいいですか?

サービスが使うサービスアカウントに、その Secret を読む権限がありません。roles/secretmanager.secretAccessor ロール(対象の Secret のみに絞ることも可能)を付与して再デプロイしてください。