😊

FastAPIとFirestoreを連携しバックエンドサーバーを、Google Cloud Runでウェブ公開する完全ガイド

に公開

皆さん、こんにちは!PythonでのWebアプリケーション開発に日々奮闘されていますか?

今回は、Pythonの軽量WebフレームワークFastAPIと、NoSQLデータベースの代表格であるGoogle Cloud Firestoreを連携させ、さらにこれらをDockerコンテナとしてGoogle Cloud Run上でWeb公開するまでの一連のプロセスを、徹底的に解説します。

このガイドは、私が実際の開発で直面した問題や解決策を盛り込んでいるため、**ローカル環境でのWSLやDockerのセットアップから、Google Cloud Platform (GCP) の各種設定、そしてFirestoreの認証周りの「落とし穴」**まで、つまづきやすいポイントを丁寧にフォローします。このガイドを読み終える頃には、あなたのFastAPIアプリケーションがインターネット上にデプロイされているはずです!

このガイドの対象読者とゴール

  • 対象読者: FastAPI、Firestore、Docker、GCP(特にCloud Run)に興味がある方。ローカル環境でのWSL/Dockerのセットアップにつまずいた経験がある方。
  • ゴール: あなたのFastAPIアプリケーションをGoogle Cloud Runにデプロイし、公開URLを通じてインターネットからアクセスできるようにする。

1. はじめに:プロジェクトの全体像と前提条件

今回デプロイするアプリケーションは、以下のような構造と機能を想定しています。

  • FastAPI: Python製のWeb APIフレームワーク。
  • Firestore: Google Cloudが提供するNoSQLデータベース。
  • Docker: アプリケーションとその実行環境をコンテナ化し、どこでも同じように動作させるための技術。
  • Google Cloud Run: Dockerコンテナをデプロイし、フルマネージドでWeb公開できるGCPのサービス。

1.1. 前提となるファイル構成

あなたのプロジェクトが、例えば以下のようなファイル構成になっていることを確認してください。

your_project/
├── backend/
│   ├── backend_main.py             # FastAPIアプリケーションのエントリポイント
│   ├── firestore_service.py        # Firestoreデータ取得ロジックなど
│   ├── graph_generator.py          # グラフ生成ロジックなど
│   ├── Dockerfile                  # Dockerイメージビルド指示
│   └── requirements.txt            # Pythonの依存関係
└── (その他のフロントエンドや設定ファイルなど)

1.2. 必要なツールとアカウント

  • Google Cloud Platform (GCP) アカウント: クレジットカード情報の登録が必要です(無料枠あり)。
  • Google Cloud SDK (gcloud CLI): コマンドラインからGCPを操作するためのツール。
  • Docker Desktop: ローカルでDockerコンテナをビルド・実行するためのツール(Windowsの場合WSL2が必要)。
  • Python 3.8以上: ローカル開発用。

2. 地獄からの生還!ローカル環境(WSL2/Docker Desktop)の完全構築

今回の開発で私が最も苦戦し、時間を費やしたのがこのローカル環境の構築でした。「Docker Engine stopped」や「WSLが動かない」といったエラーに直面し、何度も試行錯誤を繰り返しました。最終的には、DockerデスクトップアプリからDockerエンジンを停止させ、PCを再起動するというシンプルな操作で解決し、正直拍子抜けしたものです。「案外、基本的なこと」が解決の糸口になることも多いと痛感しましたね。

もし、私の事例のように「簡単な操作で解決しない」「より深刻な環境の不安定さに悩まされている」場合は、以下に示す**「WSL2とDocker Desktopの完全クリーンインストール」**を試してみてください。私が解決しようと試行錯誤した際の、より根本的な解決方法をまとめたものです。

WSL2とDocker Desktopの完全クリーンインストール手順

既存環境が不安定な場合、以下の手順で完全に再インストールすることをお勧めします。

--- ⚠️注意: 以下の手順では既存のWSLディストリビューションデータやDockerの設定が削除される可能性があります。必要であれば事前にバックアップを取ってください。管理者権限のPowerShellまたはコマンドプロンプトで実行します。 ---

  1. Docker Desktop の完全に終了:
    タスクバーのDockerクジラアイコンを右クリックし、「Quit Docker Desktop」を選択します。

  2. 既存WSLディストリビューションの削除 (任意だが推奨):
    管理者権限のPowerShellで実行します。

    wsl --list --verbose
    # ↑表示された各ディストリビューション名(例: Ubuntu)をメモし、以下のコマンドで削除
    wsl --unregister <ディストリビューション名>
    # 全てのディストリビューションを削除したら、WSLをシャットダウン
    wsl --shutdown
    
  3. Windows機能の無効化:
    Windowsの検索バーに「Windows の機能の有効化または無効化」と入力して開き、以下をチェック解除します。

    • Windows Subsystem for Linux
    • Virtual Machine Platform
    • Hyper-V (Windows Pro/Enterpriseのみ。Hyper-Vがない場合はスキップ)
      設定後、PCを再起動してください。
  4. Docker Desktop の完全アンインストール:
    「設定」>「アプリ」>「アプリと機能」からDocker Desktopをアンインストールします。この際、アンインストールウィザードで**「Remove configuration and user data」にチェックを入れることを強く推奨します。アンインストール後、PCを再起動**します。

  5. Windows機能の再有効化:
    「Windows の機能の有効化または無効化」を再度開き、上記3項目(WSL、Virtual Machine Platform、Hyper-V)をチェックして有効化します。設定後、PCを再起動します。

  6. WSL2 Linuxカーネル更新プログラムパッケージのインストール:
    Microsoft公式ページから wsl_update_x64.msi をダウンロードし、インストールします。

  7. WSL2のデフォルト設定とUbuntuのインストール:
    管理者権限のPowerShellで実行します。

    wsl --set-default-version 2
    wsl --install -d Ubuntu # これがうまくいかない場合、Microsoft StoreからUbuntuを手動インストール
    

    Ubuntuのインストール後、指示に従って新しいユーザー名とパスワードを設定します。

  8. Docker Desktop の再インストール:
    Docker公式サイトから最新版をダウンロードし、インストールします。インストール時に**「Use WSL 2 instead of Hyper-V (recommended)」にチェックが入っていることを確認してください。インストール後、PCを再起動**します。

  9. Docker Desktop と WSL の動作確認:
    Docker Desktopを起動し、「Docker Desktop is running」と表示されることを確認します。
    PowerShellで以下を実行し、エラーが出ず、UbuntuがVersion 2で表示されれば成功です。

    docker ps
    wsl --list --verbose
    

これでローカルのDocker環境は万全なはずです。


3. FastAPIアプリとFirestore認証の最適化

FastAPIアプリケーションをGoogle Cloud Runにデプロイする際、Firestoreへのアクセス認証方法がローカル開発時とは異なります。ここでの調整がデプロイ成功の鍵を握ります。

3.1. backend_main.py の修正:Firestore認証コードの調整

ローカル開発で GOOGLE_APPLICATION_CREDENTIALS 環境変数やサービスアカウントキー(.json ファイル)を直接コードで指定している場合、その行は削除してください。Cloud Runでは異なる認証方法が推奨されます。

修正前 (例):

import os
# os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = "path/to/your/service-account-key.json" # この行は削除!
from firebase_admin import credentials, firestore, initialize_app
# ...

修正後 (Cloud Run向け、ローカル開発も両対応):

from firebase_admin import credentials, firestore, initialize_app

# 一般的には、アプリの初期化時にクレデンシャルを明示的に指定しないことで、
# 環境変数GOOGLE_APPLICATION_CREDENTIALS(ローカル)または
# Cloud Runのデフォルトサービスアカウント(GCP)が利用されます。
# アプリがまだ初期化されていない場合のみ初期化することで、重複初期化エラーを防ぎます。
if not firestore._apps: # アプリがまだ初期化されていない場合のみ初期化
    cred = credentials.ApplicationDefault()
    initialize_app(cred)
db = firestore.client()

credentials.ApplicationDefault() を使用すると、ローカル環境ではGOOGLE_APPLICATION_CREDENTIALS環境変数が、Cloud Run環境ではCloud Runに割り当てられたサービスアカウントが自動的に利用されるため、非常にスマートな認証処理が実現できます。

3.2. Firestore認証の仕組み(GCPでのベストプラクティス)

  • ローカル開発時:
    GOOGLE_APPLICATION_CREDENTIALSという環境変数に、ダウンロードしたサービスアカウントキー(JSONファイル)のパスを設定して認証します。

    # 例: コマンドプロンプトの場合
    set GOOGLE_APPLICATION_CREDENTIALS="C:\path\to\your\service-account-key.json"
    # 例: PowerShellの場合
    $env:GOOGLE_APPLICATION_CREDENTIALS="C:\path\to\your\service-account-key.json"
    
  • Google Cloud Run デプロイ時 (推奨):
    Cloud Runのデフォルトのサービスアカウントを利用します。backend_main.pycredentials.ApplicationDefault()を使用すると、Cloud Run環境では、自動的にCloud Runサービスに割り当てられたサービスアカウントが利用されます。**サービスアカウントキーのJSONファイルをコンテナイメージに含める必要はありません。**これはセキュリティ上非常に推奨される方法です。
    このデフォルトサービスアカウントには、Firestoreへのアクセス権限(Cloud Datastore ユーザー ロール)が付与されている必要があります(後述の「IAM権限の確認」で解説します)。

3.3. Dockerfilerequirements.txt の準備

FastAPIアプリケーションをコンテナ化するために、backend ディレクトリ内に以下のファイルを作成・確認します。

3.3.1. backend/requirements.txt

アプリケーションに必要なPythonライブラリを記述します。バージョンを固定することで、環境間の差異を防ぎます。

fastapi==0.111.0 # 使用しているバージョンに合わせる
uvicorn==0.30.1 # 使用しているバージョンに合わせる
google-cloud-firestore==2.15.0 # 使用しているバージョンに合わせる
pandas
matplotlib
python-multipart
# その他の必要なライブラリ

※バージョンは例です。ご自身の環境で使っているバージョンに合わせてください。

3.3.2. backend/Dockerfile

FastAPIアプリケーションをコンテナ化するための指示書です。各行の意味を理解して記述しましょう。

# Pythonの公式軽量イメージをベースにする (3.11は一例、利用Pythyonバージョンに合わせる)
FROM python:3.11-slim-buster

# 作業ディレクトリをコンテナ内に設定
WORKDIR /app

# ホストのrequirements.txtファイルをコンテナの/appディレクトリにコピー
COPY requirements.txt .

# 依存関係をインストール
# --no-cache-dir: pipのキャッシュを無効にし、イメージサイズを小さくする
RUN pip install --no-cache-dir -r requirements.txt

# ホストのアプリケーションコード(backendディレクトリ内の全ファイル)をコンテナの/appディレクトリにコピー
COPY . .

# FastAPIアプリケーションを起動するコマンドを定義
# Uvicornを使って0.0.0.0:8000でFastAPIを起動
# backend_main:app は backend_main.py ファイル内の app というFastAPIインスタンスを指す
CMD ["uvicorn", "backend_main:app", "--host", "0.0.0.0", "--port", "8000"]

CMD命令でuvicornを使ってFastAPIアプリケーションを起動しています。backend_main:appは、backend_main.pyファイル内のappというFastAPIインスタンスを指します。


4. GCP環境の徹底準備とDockerイメージのデプロイ

いよいよGoogle Cloud Platform (GCP) の設定を進めます。ここでの準備が、後続のデプロイをスムーズに進める上で非常に重要です。

4.1. GCPプロジェクトの選択/確認

Google Cloud Console (console.cloud.google.com) にログインし、画面上部中央のドロップダウンからあなたのGCPプロジェクト(例: analysis-stocks-tool)が選択されていることを確認します。

4.2. 必要なAPIの有効化

以下のAPIがプロジェクトで有効になっている必要があります。

  • Cloud Run API
  • Container Registry API (または Artifact Registry API)
  • Firestore API
  • Identity and Access Management (IAM) API

確認と有効化の方法:

  • 方法A (推奨): gcloud run deploy コマンドで自動有効化
    後述のgcloud run deployコマンドを実行する際に、必要なAPIが有効になっていなければ「Do you want to enable these APIs... (Y/n)?」と聞かれます。ここで Y を入力すれば自動で有効化されます。

  • 方法B: Google Cloud Console で手動有効化
    Cloud Consoleのナビゲーションメニュー(左上の三本線)から「API とサービス」>「有効なAPIとサービス」に移動。「API とサービスの有効化」をクリックし、各API名(例: "Cloud Run API")を検索して有効化します。

4.3. 請求アカウントの有効化(最重要!)

Cloud RunやFirestoreなどのサービスは、無料枠を超えると課金が発生します。そのため、プロジェクトに有効な請求アカウントが紐付けられている必要があります。私が直面した「Billing account ... is not found.」エラーは、まさにこれが原因でした。

  1. Google Cloud Console (console.cloud.google.com) にログイン。
  2. ナビゲーションメニューから「請求」(または「Billing」)をクリック。
  3. ここにあなたの請求アカウント情報が表示されるはずです。
  4. 「請求アカウントがありません」といった表示の場合
    「請求アカウントを作成」または「請求を有効にする」ボタンをクリックし、指示に従ってクレジットカード情報を登録し、請求アカウントを有効にしてください。
  5. すでに請求アカウントがある場合
    現在選択されているGCPプロジェクトがその請求アカウントに紐付けられていることを確認します。紐付けられていなければ、リンクするオプションがあるはずです。

4.4. IAM権限の確認

Cloud RunサービスがFirestoreにアクセスできるように、適切な権限が付与されている必要があります。

  1. Google Cloud Console のナビゲーションメニューから「IAM と管理」>「IAM」のページに移動します。
  2. プリンシパル(メンバー)のリストから、あなたのプロジェクトのCompute Engine のデフォルトサービスアカウント(形式: プロジェクト番号-compute@developer.gserviceaccount.com。例: 487175616385-compute@developer.gserviceaccount.com)を探します。
  3. このサービスアカウントに、以下のロールが付与されていることを確認します。
    • Cloud Datastore ユーザー (roles/datastore.user)
  4. もしなければ、「アクセス権を付与」からこのロールを追加してください。

4.5. Google Cloud SDK (gcloud CLI) の準備

コマンドラインからGCPリソースを操作するためのツールです。

4.5.1. gcloud CLI のインストール

まだインストールしていない場合、Google Cloud SDK のインストール ページからWindows版インストーラーをダウンロードし、実行します。インストール中に**「Add gcloud CLI to your PATH」オプションにチェックを入れる**ことを忘れないでください。これが「gcloud' は、内部コマンドまたは外部コマンドとして認識されていません」エラーの主な原因です。インストール後、コマンドプロンプトを再起動します。

4.5.2. gcloud CLI の初期設定と認証

  1. 認証:

    gcloud auth login
    

    ブラウザが開き、Googleアカウントでログインするよう求められます。成功すると、「You are signed in as: [your-email@gmail.com].」と表示されます。

  2. プロジェクトの選択:
    ログイン後、使用するGCPプロジェクトを選択するよう促されます。Pick cloud project to use: のリストから、あなたのプロジェクトID(例: analysis-stocks-tool)に対応する数字(例: 1)を入力してEnterを押します。「Your current project has been set to: [analysis-stocks-tool].」と表示されれば成功です。

  3. Dockerクライアントの認証:
    Container Registry (GCR) や Artifact Registry にDockerイメージをプッシュするための認証情報を設定します。

    gcloud auth configure-docker
    

    Docker configuration file updated.」と表示されれば成功です。私が直面した「Unauthenticated request」エラーは、これが未実行または認証切れが原因でした。

4.6. Dockerイメージのビルドとプッシュ

あなたのFastAPIアプリケーションをDockerコンテナイメージとしてビルドし、GCPのレジストリにアップロードします。

  1. backend ディレクトリへ移動:
    コマンドプロンプトで、Dockerfileとアプリケーションコードがあるbackendディレクトリに移動します。

    cd path/to/your_project/backend/
    
  2. Dockerイメージのビルド:
    analysis-stocks-toolはあなたのGCPプロジェクトIDに置き換えてください。

    docker build -t gcr.io/analysis-stocks-tool/stock-api:latest .
    
    • -t: イメージにタグを付けます。gcr.io/YOUR_PROJECT_ID/イメージ名:タグ の形式です。
    • .: 現在のディレクトリをビルドコンテキストとして使用します。
      成功すると、各ステップの後に => のような表示が続き、最終的に Successfully built <イメージID> と表示されます。
  3. DockerイメージをGCR (または Artifact Registry) にプッシュ:
    ビルドしたイメージをGoogle Cloudのレジストリにアップロードします。

    docker push gcr.io/analysis-stocks-tool/stock-api:latest
    

    gcr.ioはGoogle Container Registryのホスト名です。もしArtifact Registryを使用している場合は、asia-northeast1-docker.pkg.dev/YOUR_PROJECT_ID/YOUR_REPO_NAME/stock-api:latestのようなパスになります。
    成功すると、各レイヤーがAlready existsとなるか、Pushedとなり、最終的にlatest: digest: ...のようなメッセージが表示されます。私が経験した「Unauthenticated request」エラーが出なければOKです。


5. いざ本番へ!Google Cloud Runへのデプロイと確認、そして費用管理

いよいよあなたのFastAPIアプリケーションをインターネットに公開する最終ステップです!

5.1. Google Cloud Run へのデプロイ

Cloud Runへのデプロイコマンドを実行します。すべてのオプションをスペースで区切りながら1行でコマンドプロンプトに貼り付けて実行してください。私が直面した「unrecognized arguments」エラーは、コマンド途中の \ (バックスラッシュ)による改行が原因でした。

gcloud run deploy stock-api --image gcr.io/analysis-stocks-tool/stock-api:latest --platform managed --region asia-northeast1 --allow-unauthenticated --port 8000
  • stock-api: Cloud Runサービスの名前。任意で変更可能。
  • --image: ステップ4でプッシュしたイメージのパスを指定(gcr.ioまたはArtifact Registryのパス)。
  • --platform managed: フルマネージド環境を指定します。
  • --region asia-northeast1: サービスをデプロイするリージョン。Firestoreの場所に近い方が望ましいです。
  • --allow-unauthenticated: 重要! これにより、認証なしでAPIにアクセス可能になります(公開API)。
  • --port 8000: コンテナがリッスンするポート(Dockerfileと合わせます)。

プロンプトへの応答:

  • Do you want to enable these APIs... (Y/n)?」と聞かれたら、Y を入力。
  • Allow unauthenticated invocations to new service (stock-api)? (y/N)」と聞かれたら、y を入力。

デプロイの完了:

数分後、「Service [stock-api] revision [stock-api-00001-xxxx] has been deployed and is serving 100 percent of traffic.」と表示されます。
そして、Service URL: https://stock-api-xxxxxxxxxx.asia-northeast1.run.app のようなURLが表示されます。これがあなたのFastAPIアプリケーションの公開URLです!

5.2. デプロイの確認と動作テスト

表示された Service URL にWebブラウザでアクセスしてみましょう。

  • FastAPIのルート (/) にアクセスして、デフォルトの{"detail":"Not Found"}やあなたが設定したレスポンスが返ってくるかを確認します。
  • https://[Service URL]/financial_data/AAPL のように、定義したAPIエンドポイントにアクセスし、Firestoreからデータが正常に取得できるかを確認します。

正常に動作していれば、公開は完璧です!

5.3. 費用管理:サービスの一時停止・削除

公開確認後、課金を最小限に抑えるために、すぐにサービスを停止または削除することを強くお勧めします。Cloud Runはリクエストがない間は課金されませんが、万が一のリソース消費を防ぐためです。

5.3.1. Cloud Run サービスを削除する(最も確実)

これが最も推奨される方法で、完全に課金が停止します。

  1. Google Cloud Console のナビゲーションメニューから「Cloud Run」ページに移動。
  2. デプロイしたサービス名(stock-api)の左側にあるチェックボックスにチェック。
  3. 画面上部にある「削除」ボタンをクリック。
  4. 確認ダイアログでサービス名を入力し、「削除」をクリック。

5.3.2. Dockerイメージを削除する (任意)

Cloud Runサービスを削除しても、Container Registry/Artifact Registryに保存されたDockerイメージは残ります。これはストレージ料金がかかる場合がありますが、非常に微々たるものです。気になる場合は削除できます。

  1. Google Cloud Console のナビゲーションメニューから「Container Registry」(または「Artifact Registry」)に移動。
  2. stock-apiリポジトリ(またはイメージ)を探し、削除オプションを実行。

まとめと次のステップ

皆さん、本当にお疲れ様でした!この長かったガイドを通じて、あなたはFastAPIアプリケーションをGoogle Cloud Runにデプロイし、Firestoreと連携させてDockerコンテナとして公開するという、一連の複雑ながらも非常に実践的なプロセスをマスターしました。

具体的には、「Docker Engine stopped」などのトラブルを乗り越えるWSL2とDocker Desktopの完全クリーンインストールから始まり、FastAPIのFirestore認証のベストプラクティス、適切なDockerfilerequirements.txtの作成、そしてGCP環境のきめ細やかな設定(API有効化、請求アカウント、IAM権限)まで、デプロイに必要な全てのステップを網羅しました。最終的にgcloud CLIを使ったDockerイメージのビルド、プッシュ、そしてCloud Runへのデプロイを成功させ、あなたのアプリケーションをインターネットに公開できたはずです。

この経験は、単なる知識の習得に留まらず、情報工学の概念を実際のクラウドサービスと結びつける貴重な実践となります。トラブルシューティングの経験は、今後の開発において大きな自信となるでしょう。

今回デプロイしたアプリケーションを基盤として、さらに機能を拡張したり、別のGCPサービス(Cloud Functions、Cloud SQLなど)と連携させたりすることで、あなたのスキルは飛躍的に向上します。ぜひ、今回の学びを活かして、次のプロジェクトに挑戦してみてください!

Discussion